From a34b3629a2df5c764c98bdd7b68343b63717d19e Mon Sep 17 00:00:00 2001 From: idrissrio Date: Tue, 19 Aug 2025 09:44:50 +0200 Subject: [PATCH 1/6] Java: accept new test results after extractor update --- .../test.expected | 120 ++++++------------ .../reflection/reflection.expected | 1 + .../test.expected | 117 ++++++----------- .../reflection/reflection.expected | 1 + 4 files changed, 77 insertions(+), 162 deletions(-) diff --git a/java/ql/test-kotlin1/library-tests/java-kotlin-collection-type-generic-methods/test.expected b/java/ql/test-kotlin1/library-tests/java-kotlin-collection-type-generic-methods/test.expected index b901340b9642..a56980d10ac4 100644 --- a/java/ql/test-kotlin1/library-tests/java-kotlin-collection-type-generic-methods/test.expected +++ b/java/ql/test-kotlin1/library-tests/java-kotlin-collection-type-generic-methods/test.expected @@ -16,30 +16,6 @@ methodWithDuplicate | AbstractCollection | removeAll | Collection | | AbstractCollection | retainAll | Collection | | AbstractCollection | toArray | T[] | -| AbstractCollection> | add | Entry | -| AbstractCollection> | addAll | Collection> | -| AbstractCollection> | contains | Object | -| AbstractCollection> | containsAll | Collection | -| AbstractCollection> | remove | Object | -| AbstractCollection> | removeAll | Collection | -| AbstractCollection> | retainAll | Collection | -| AbstractCollection> | toArray | T[] | -| AbstractCollection | add | K | -| AbstractCollection | addAll | Collection | -| AbstractCollection | contains | Object | -| AbstractCollection | containsAll | Collection | -| AbstractCollection | remove | Object | -| AbstractCollection | removeAll | Collection | -| AbstractCollection | retainAll | Collection | -| AbstractCollection | toArray | T[] | -| AbstractCollection | add | Runnable | -| AbstractCollection | addAll | Collection | -| AbstractCollection | contains | Object | -| AbstractCollection | containsAll | Collection | -| AbstractCollection | remove | Object | -| AbstractCollection | removeAll | Collection | -| AbstractCollection | retainAll | Collection | -| AbstractCollection | toArray | T[] | | AbstractCollection | add | String | | AbstractCollection | addAll | Collection | | AbstractCollection | contains | Object | @@ -56,14 +32,6 @@ methodWithDuplicate | AbstractCollection | removeAll | Collection | | AbstractCollection | retainAll | Collection | | AbstractCollection | toArray | T[] | -| AbstractCollection | add | V | -| AbstractCollection | addAll | Collection | -| AbstractCollection | contains | Object | -| AbstractCollection | containsAll | Collection | -| AbstractCollection | remove | Object | -| AbstractCollection | removeAll | Collection | -| AbstractCollection | retainAll | Collection | -| AbstractCollection | toArray | T[] | | AbstractList | add | E | | AbstractList | add | int | | AbstractList | addAll | Collection | @@ -103,14 +71,14 @@ methodWithDuplicate | AbstractMap | put | V | | AbstractMap | putAll | Map | | AbstractMap | remove | Object | -| AbstractMap> | containsKey | Object | -| AbstractMap> | containsValue | Object | -| AbstractMap> | equals | Object | -| AbstractMap> | get | Object | -| AbstractMap> | put | Entry | -| AbstractMap> | put | Identity | -| AbstractMap> | putAll | Map> | -| AbstractMap> | remove | Object | +| AbstractMap | containsKey | Object | +| AbstractMap | containsValue | Object | +| AbstractMap | equals | Object | +| AbstractMap | get | Object | +| AbstractMap | put | Identity | +| AbstractMap | put | Object | +| AbstractMap | putAll | Map | +| AbstractMap | remove | Object | | AbstractMap | containsKey | Object | | AbstractMap | containsValue | Object | | AbstractMap | equals | Object | @@ -179,17 +147,6 @@ methodWithDuplicate | Collection | retainAll | Collection | | Collection | toArray | IntFunction | | Collection | toArray | T[] | -| Collection | add | Runnable | -| Collection | addAll | Collection | -| Collection | contains | Object | -| Collection | containsAll | Collection | -| Collection | equals | Object | -| Collection | remove | Object | -| Collection | removeAll | Collection | -| Collection | removeIf | Predicate | -| Collection | retainAll | Collection | -| Collection | toArray | IntFunction | -| Collection | toArray | T[] | | Collection | add | String | | Collection | addAll | Collection | | Collection | contains | Object | @@ -332,37 +289,36 @@ methodWithDuplicate | Map | replace | K | | Map | replace | V | | Map | replaceAll | BiFunction | -| Map> | compute | BiFunction,? extends Entry> | -| Map> | compute | Identity | -| Map> | computeIfAbsent | Function> | -| Map> | computeIfAbsent | Identity | -| Map> | computeIfPresent | BiFunction,? extends Entry> | -| Map> | computeIfPresent | Identity | -| Map> | containsKey | Object | -| Map> | containsValue | Object | -| Map> | copyOf | Map | -| Map> | entry | K | -| Map> | entry | V | -| Map> | equals | Object | -| Map> | forEach | BiConsumer> | -| Map> | get | Object | -| Map> | getOrDefault | Entry | -| Map> | getOrDefault | Object | -| Map> | merge | BiFunction,? super Entry,? extends Entry> | -| Map> | merge | Entry | -| Map> | merge | Identity | -| Map> | of | K | -| Map> | of | V | -| Map> | ofEntries | Entry[] | -| Map> | put | Entry | -| Map> | put | Identity | -| Map> | putAll | Map> | -| Map> | putIfAbsent | Entry | -| Map> | putIfAbsent | Identity | -| Map> | remove | Object | -| Map> | replace | Entry | -| Map> | replace | Identity | -| Map> | replaceAll | BiFunction,? extends Entry> | +| Map | compute | BiFunction | +| Map | compute | Identity | +| Map | computeIfAbsent | Function | +| Map | computeIfAbsent | Identity | +| Map | computeIfPresent | BiFunction | +| Map | computeIfPresent | Identity | +| Map | containsKey | Object | +| Map | containsValue | Object | +| Map | copyOf | Map | +| Map | entry | K | +| Map | entry | V | +| Map | equals | Object | +| Map | forEach | BiConsumer | +| Map | get | Object | +| Map | getOrDefault | Object | +| Map | merge | BiFunction | +| Map | merge | Identity | +| Map | merge | Object | +| Map | of | K | +| Map | of | V | +| Map | ofEntries | Entry[] | +| Map | put | Identity | +| Map | put | Object | +| Map | putAll | Map | +| Map | putIfAbsent | Identity | +| Map | putIfAbsent | Object | +| Map | remove | Object | +| Map | replace | Identity | +| Map | replace | Object | +| Map | replaceAll | BiFunction | | Map | compute | BiFunction | | Map | compute | K | | Map | computeIfAbsent | Function | diff --git a/java/ql/test-kotlin1/library-tests/reflection/reflection.expected b/java/ql/test-kotlin1/library-tests/reflection/reflection.expected index 7ce456cdcbb2..3bc2f9ce67d6 100644 --- a/java/ql/test-kotlin1/library-tests/reflection/reflection.expected +++ b/java/ql/test-kotlin1/library-tests/reflection/reflection.expected @@ -289,6 +289,7 @@ compGenerated | file:///LongProgression.class:0:0:0:0 | spliterator | Forwarder for a Kotlin class inheriting an interface default method | | file:///LongRange.class:0:0:0:0 | forEach | Forwarder for a Kotlin class inheriting an interface default method | | file:///LongRange.class:0:0:0:0 | spliterator | Forwarder for a Kotlin class inheriting an interface default method | +| file:///String.class:0:0:0:0 | getChars | Forwarder for a Kotlin class inheriting an interface default method | | file:///String.class:0:0:0:0 | isEmpty | Forwarder for a Kotlin class inheriting an interface default method | | reflection.kt:7:49:7:54 | new Function2(...) { ... } | The class around a local function, a lambda, or a function reference | | reflection.kt:10:38:10:42 | new KProperty1(...) { ... } | The class around a local function, a lambda, or a function reference | diff --git a/java/ql/test-kotlin2/library-tests/java-kotlin-collection-type-generic-methods/test.expected b/java/ql/test-kotlin2/library-tests/java-kotlin-collection-type-generic-methods/test.expected index 03e86e2d2a18..2495c1fc1572 100644 --- a/java/ql/test-kotlin2/library-tests/java-kotlin-collection-type-generic-methods/test.expected +++ b/java/ql/test-kotlin2/library-tests/java-kotlin-collection-type-generic-methods/test.expected @@ -16,30 +16,6 @@ methodWithDuplicate | AbstractCollection | removeAll | Collection | | AbstractCollection | retainAll | Collection | | AbstractCollection | toArray | T[] | -| AbstractCollection> | add | Entry | -| AbstractCollection> | addAll | Collection> | -| AbstractCollection> | contains | Object | -| AbstractCollection> | containsAll | Collection | -| AbstractCollection> | remove | Object | -| AbstractCollection> | removeAll | Collection | -| AbstractCollection> | retainAll | Collection | -| AbstractCollection> | toArray | T[] | -| AbstractCollection | add | K | -| AbstractCollection | addAll | Collection | -| AbstractCollection | contains | Object | -| AbstractCollection | containsAll | Collection | -| AbstractCollection | remove | Object | -| AbstractCollection | removeAll | Collection | -| AbstractCollection | retainAll | Collection | -| AbstractCollection | toArray | T[] | -| AbstractCollection | add | Runnable | -| AbstractCollection | addAll | Collection | -| AbstractCollection | contains | Object | -| AbstractCollection | containsAll | Collection | -| AbstractCollection | remove | Object | -| AbstractCollection | removeAll | Collection | -| AbstractCollection | retainAll | Collection | -| AbstractCollection | toArray | T[] | | AbstractCollection | add | String | | AbstractCollection | addAll | Collection | | AbstractCollection | contains | Object | @@ -56,14 +32,6 @@ methodWithDuplicate | AbstractCollection | removeAll | Collection | | AbstractCollection | retainAll | Collection | | AbstractCollection | toArray | T[] | -| AbstractCollection | add | V | -| AbstractCollection | addAll | Collection | -| AbstractCollection | contains | Object | -| AbstractCollection | containsAll | Collection | -| AbstractCollection | remove | Object | -| AbstractCollection | removeAll | Collection | -| AbstractCollection | retainAll | Collection | -| AbstractCollection | toArray | T[] | | AbstractList | add | E | | AbstractList | add | int | | AbstractList | addAll | Collection | @@ -103,14 +71,14 @@ methodWithDuplicate | AbstractMap | put | V | | AbstractMap | putAll | Map | | AbstractMap | remove | Object | -| AbstractMap> | containsKey | Object | -| AbstractMap> | containsValue | Object | -| AbstractMap> | equals | Object | -| AbstractMap> | get | Object | -| AbstractMap> | put | Entry | -| AbstractMap> | put | Identity | -| AbstractMap> | putAll | Map> | -| AbstractMap> | remove | Object | +| AbstractMap | containsKey | Object | +| AbstractMap | containsValue | Object | +| AbstractMap | equals | Object | +| AbstractMap | get | Object | +| AbstractMap | put | Identity | +| AbstractMap | put | Object | +| AbstractMap | putAll | Map | +| AbstractMap | remove | Object | | AbstractMap | containsKey | Object | | AbstractMap | containsValue | Object | | AbstractMap | equals | Object | @@ -176,16 +144,6 @@ methodWithDuplicate | Collection | retainAll | Collection | | Collection | toArray | IntFunction | | Collection | toArray | T[] | -| Collection | add | Runnable | -| Collection | addAll | Collection | -| Collection | contains | Object | -| Collection | containsAll | Collection | -| Collection | remove | Object | -| Collection | removeAll | Collection | -| Collection | removeIf | Predicate | -| Collection | retainAll | Collection | -| Collection | toArray | IntFunction | -| Collection | toArray | T[] | | Collection | add | String | | Collection | addAll | Collection | | Collection | contains | Object | @@ -325,36 +283,35 @@ methodWithDuplicate | Map | replace | K | | Map | replace | V | | Map | replaceAll | BiFunction | -| Map> | compute | BiFunction,? extends Entry> | -| Map> | compute | Identity | -| Map> | computeIfAbsent | Function> | -| Map> | computeIfAbsent | Identity | -| Map> | computeIfPresent | BiFunction,? extends Entry> | -| Map> | computeIfPresent | Identity | -| Map> | containsKey | Object | -| Map> | containsValue | Object | -| Map> | copyOf | Map | -| Map> | entry | K | -| Map> | entry | V | -| Map> | forEach | BiConsumer> | -| Map> | get | Object | -| Map> | getOrDefault | Entry | -| Map> | getOrDefault | Object | -| Map> | merge | BiFunction,? super Entry,? extends Entry> | -| Map> | merge | Entry | -| Map> | merge | Identity | -| Map> | of | K | -| Map> | of | V | -| Map> | ofEntries | Entry[] | -| Map> | put | Entry | -| Map> | put | Identity | -| Map> | putAll | Map> | -| Map> | putIfAbsent | Entry | -| Map> | putIfAbsent | Identity | -| Map> | remove | Object | -| Map> | replace | Entry | -| Map> | replace | Identity | -| Map> | replaceAll | BiFunction,? extends Entry> | +| Map | compute | BiFunction | +| Map | compute | Identity | +| Map | computeIfAbsent | Function | +| Map | computeIfAbsent | Identity | +| Map | computeIfPresent | BiFunction | +| Map | computeIfPresent | Identity | +| Map | containsKey | Object | +| Map | containsValue | Object | +| Map | copyOf | Map | +| Map | entry | K | +| Map | entry | V | +| Map | forEach | BiConsumer | +| Map | get | Object | +| Map | getOrDefault | Object | +| Map | merge | BiFunction | +| Map | merge | Identity | +| Map | merge | Object | +| Map | of | K | +| Map | of | V | +| Map | ofEntries | Entry[] | +| Map | put | Identity | +| Map | put | Object | +| Map | putAll | Map | +| Map | putIfAbsent | Identity | +| Map | putIfAbsent | Object | +| Map | remove | Object | +| Map | replace | Identity | +| Map | replace | Object | +| Map | replaceAll | BiFunction | | Map | compute | BiFunction | | Map | compute | K | | Map | computeIfAbsent | Function | diff --git a/java/ql/test-kotlin2/library-tests/reflection/reflection.expected b/java/ql/test-kotlin2/library-tests/reflection/reflection.expected index 4074866da65f..b5de2b1adea3 100644 --- a/java/ql/test-kotlin2/library-tests/reflection/reflection.expected +++ b/java/ql/test-kotlin2/library-tests/reflection/reflection.expected @@ -329,6 +329,7 @@ compGenerated | file:///SignStyle.class:0:0:0:0 | getEntries | Default property accessor | | file:///StackWalker$ExtendedOption.class:0:0:0:0 | getEntries | Default property accessor | | file:///StackWalker$Option.class:0:0:0:0 | getEntries | Default property accessor | +| file:///String.class:0:0:0:0 | getChars | Forwarder for a Kotlin class inheriting an interface default method | | file:///String.class:0:0:0:0 | isEmpty | Forwarder for a Kotlin class inheriting an interface default method | | file:///TextStyle.class:0:0:0:0 | getEntries | Default property accessor | | file:///Thread$State.class:0:0:0:0 | getEntries | Default property accessor | From f762cf15fd55623d9d97cfa46ecfd0687e4706b5 Mon Sep 17 00:00:00 2001 From: idrissrio Date: Tue, 2 Sep 2025 12:03:45 +0200 Subject: [PATCH 2/6] Java: add dataflow test for newly added KDF API --- .../dataflow/kdf/KDFDataflowTest.java | 70 +++++++++++++++++++ .../test/library-tests/dataflow/kdf/options | 1 + .../library-tests/dataflow/kdf/test.expected | 0 .../test/library-tests/dataflow/kdf/test.ql | 24 +++++++ 4 files changed, 95 insertions(+) create mode 100644 java/ql/test/library-tests/dataflow/kdf/KDFDataflowTest.java create mode 100644 java/ql/test/library-tests/dataflow/kdf/options create mode 100644 java/ql/test/library-tests/dataflow/kdf/test.expected create mode 100644 java/ql/test/library-tests/dataflow/kdf/test.ql diff --git a/java/ql/test/library-tests/dataflow/kdf/KDFDataflowTest.java b/java/ql/test/library-tests/dataflow/kdf/KDFDataflowTest.java new file mode 100644 index 000000000000..46885be1f4ca --- /dev/null +++ b/java/ql/test/library-tests/dataflow/kdf/KDFDataflowTest.java @@ -0,0 +1,70 @@ +import javax.crypto.KDF; +import javax.crypto.spec.HKDFParameterSpec; + +public class KDFDataflowTest { + public static void main(String[] args) throws Exception { + String userInput = args[0]; // source + byte[] taintedBytes = userInput.getBytes(); + + testBuilderPattern(taintedBytes); + testSeparateBuilder(taintedBytes); + testKDFWithSalt(taintedBytes); + testStaticParameterSpec(taintedBytes); + testCleanUsage(); + } + + public static void testBuilderPattern(byte[] taintedIKM) throws Exception { + HKDFParameterSpec.Builder builder = HKDFParameterSpec.ofExtract(); + builder.addIKM(taintedIKM); + HKDFParameterSpec spec = builder.thenExpand("info".getBytes(), 32); + + KDF kdf = KDF.getInstance("HKDF-SHA256"); + byte[] result = kdf.deriveData(spec); + sink(result); // should flag + } + + public static void testSeparateBuilder(byte[] taintedIKM) throws Exception { + HKDFParameterSpec.Builder builder1 = HKDFParameterSpec.ofExtract(); + HKDFParameterSpec.Builder builder2 = builder1.addIKM(taintedIKM); + HKDFParameterSpec spec = builder2.thenExpand("info".getBytes(), 32); + + KDF kdf = KDF.getInstance("HKDF-SHA256"); + byte[] result = kdf.deriveData(spec); + sink(result); // should flag + } + + public static void sink(Object o) {} + + public static void testKDFWithSalt(byte[] taintedIKM) throws Exception { + HKDFParameterSpec.Builder builder = HKDFParameterSpec.ofExtract(); + builder.addIKM(taintedIKM); + builder.addSalt("sensitive-salt".getBytes()); + HKDFParameterSpec spec = builder.thenExpand("info".getBytes(), 32); + + KDF kdf = KDF.getInstance("HKDF-SHA256"); + byte[] result = kdf.deriveData(spec); + sink(result); // should flag + } + + public static void testStaticParameterSpec(byte[] taintedIKM) throws Exception { + javax.crypto.spec.SecretKeySpec secretKey = new javax.crypto.spec.SecretKeySpec(taintedIKM, "AES"); + HKDFParameterSpec spec = HKDFParameterSpec.expandOnly( + secretKey, "info".getBytes(), 32); + + KDF kdf = KDF.getInstance("HKDF-SHA256"); + byte[] result = kdf.deriveData(spec); + sink(result); // should flag + } + + public static void testCleanUsage() throws Exception { + byte[] cleanKeyMaterial = "static-key-material".getBytes(); + + HKDFParameterSpec.Builder builder = HKDFParameterSpec.ofExtract(); + builder.addIKM(cleanKeyMaterial); // clean input + HKDFParameterSpec spec = builder.thenExpand("info".getBytes(), 32); + + KDF kdf = KDF.getInstance("HKDF-SHA256"); + byte[] cleanResult = kdf.deriveData(spec); + sink(cleanResult); // should NOT flag - no taint source + } +} \ No newline at end of file diff --git a/java/ql/test/library-tests/dataflow/kdf/options b/java/ql/test/library-tests/dataflow/kdf/options new file mode 100644 index 000000000000..f4edc64c0178 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/kdf/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args --enable-preview --release 25 \ No newline at end of file diff --git a/java/ql/test/library-tests/dataflow/kdf/test.expected b/java/ql/test/library-tests/dataflow/kdf/test.expected new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/ql/test/library-tests/dataflow/kdf/test.ql b/java/ql/test/library-tests/dataflow/kdf/test.ql new file mode 100644 index 000000000000..43534d2d3d8a --- /dev/null +++ b/java/ql/test/library-tests/dataflow/kdf/test.ql @@ -0,0 +1,24 @@ +import java +import semmle.code.java.dataflow.TaintTracking + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node n) { + exists(ArrayAccess aa | + aa.getArray().(VarAccess).getVariable().hasName("args") and + n.asExpr() = aa + ) + } + + predicate isSink(DataFlow::Node n) { + exists(MethodCall ma | + ma.getMethod().hasName("sink") and + n.asExpr() = ma.getAnArgument() + ) + } +} + +module Flow = TaintTracking::Global; + +from DataFlow::Node src, DataFlow::Node sink +where Flow::flow(src, sink) +select src, sink From dba12f3ea3308f637098a2f738045800dba1950c Mon Sep 17 00:00:00 2001 From: idrissrio Date: Tue, 2 Sep 2025 12:04:55 +0200 Subject: [PATCH 3/6] Java: Add MaDs for `java.crypto.KDF` --- java/ql/lib/ext/javax.crypto.model.yml | 15 +++++++++++++++ java/ql/lib/ext/javax.crypto.spec.model.yml | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/java/ql/lib/ext/javax.crypto.model.yml b/java/ql/lib/ext/javax.crypto.model.yml index 2b3bfc1abe85..dfdbb3cc7033 100644 --- a/java/ql/lib/ext/javax.crypto.model.yml +++ b/java/ql/lib/ext/javax.crypto.model.yml @@ -7,6 +7,21 @@ extensions: - ["javax.crypto", "Cipher", True, "init", "(int,Key,AlgorithmParameterSpec,SecureRandom)", "", "Argument[2]", "encryption-iv", "manual"] - ["javax.crypto", "Cipher", False, "unwrap", "(byte[],String,int)", "", "Argument[0]", "credentials-key", "hq-generated"] - ["javax.crypto", "CipherSpi", True, "engineUnwrap", "(byte[],String,int)", "", "Argument[0]", "credentials-key", "hq-generated"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["javax.crypto", "KDF", False, "getInstance", "(String)", "", "Argument[0]", "ReturnValue.SyntheticField[javax.crypto.KDF.algorithm]", "value", "manual"] + - ["javax.crypto", "KDF", False, "getInstance", "(String,Provider)", "", "Argument[0]", "ReturnValue.SyntheticField[javax.crypto.KDF.algorithm]", "value", "manual"] + - ["javax.crypto", "KDF", False, "getInstance", "(String,String)", "", "Argument[0]", "ReturnValue.SyntheticField[javax.crypto.KDF.algorithm]", "value", "manual"] + - ["javax.crypto", "KDF", False, "getInstance", "(String,KDFParameters)", "", "Argument[0]", "ReturnValue.SyntheticField[javax.crypto.KDF.algorithm]", "value", "manual"] + - ["javax.crypto", "KDF", False, "getInstance", "(String,KDFParameters,Provider)", "", "Argument[0]", "ReturnValue.SyntheticField[javax.crypto.KDF.algorithm]", "value", "manual"] + - ["javax.crypto", "KDF", False, "getInstance", "(String,KDFParameters,String)", "", "Argument[0]", "ReturnValue.SyntheticField[javax.crypto.KDF.algorithm]", "value", "manual"] + - ["javax.crypto", "KDF", True, "getAlgorithm", "()", "", "Argument[this].SyntheticField[javax.crypto.KDF.algorithm]", "ReturnValue", "value", "manual"] + - ["javax.crypto", "KDF", True, "getProvider", "()", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["javax.crypto", "KDF", True, "deriveKey", "(String,AlgorithmParameterSpec)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["javax.crypto", "KDF", True, "deriveData", "(AlgorithmParameterSpec)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.crypto", "SecretKey", True, "getEncoded", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - addsTo: pack: codeql/java-all extensible: neutralModel diff --git a/java/ql/lib/ext/javax.crypto.spec.model.yml b/java/ql/lib/ext/javax.crypto.spec.model.yml index d2b7dbc99b8d..02cb3494fbac 100644 --- a/java/ql/lib/ext/javax.crypto.spec.model.yml +++ b/java/ql/lib/ext/javax.crypto.spec.model.yml @@ -7,6 +7,24 @@ extensions: - ["javax.crypto.spec", "GCMParameterSpec", True, "GCMParameterSpec", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] - ["javax.crypto.spec", "RC2ParameterSpec", True, "RC2ParameterSpec", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] - ["javax.crypto.spec", "RC5ParameterSpec", True, "RC5ParameterSpec", "", "", "Argument[3]", "Argument[this]", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(byte[])", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(byte[])", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(SecretKey)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(SecretKey)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(SecretKey)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(byte[])", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(byte[])", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(SecretKey)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(SecretKey)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(SecretKey)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "thenExpand", "(byte[],int)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "thenExpand", "(byte[],int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec", False, "expandOnly", "(SecretKey,byte[],int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec", False, "expandOnly", "(SecretKey,byte[],int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "SecretKeySpec", False, "SecretKeySpec", "(byte[],String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["javax.crypto.spec", "SecretKeySpec", False, "SecretKeySpec", "(byte[],int,int,String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - addsTo: pack: codeql/java-all extensible: sinkModel From ae786dee5ce6ff3cc5072c35d6567629f9545a41 Mon Sep 17 00:00:00 2001 From: idrissrio Date: Tue, 2 Sep 2025 12:05:19 +0200 Subject: [PATCH 4/6] Java: accept new test results --- java/ql/test/library-tests/dataflow/kdf/test.expected | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/ql/test/library-tests/dataflow/kdf/test.expected b/java/ql/test/library-tests/dataflow/kdf/test.expected index e69de29bb2d1..a53c17f410e9 100644 --- a/java/ql/test/library-tests/dataflow/kdf/test.expected +++ b/java/ql/test/library-tests/dataflow/kdf/test.expected @@ -0,0 +1,4 @@ +| KDFDataflowTest.java:6:28:6:34 | ...[...] | KDFDataflowTest.java:23:14:23:19 | result | +| KDFDataflowTest.java:6:28:6:34 | ...[...] | KDFDataflowTest.java:33:14:33:19 | result | +| KDFDataflowTest.java:6:28:6:34 | ...[...] | KDFDataflowTest.java:46:14:46:19 | result | +| KDFDataflowTest.java:6:28:6:34 | ...[...] | KDFDataflowTest.java:56:14:56:19 | result | \ No newline at end of file From ccfbf55c44320daf47850bd5f045b46e9cf78828 Mon Sep 17 00:00:00 2001 From: idrissrio Date: Tue, 2 Sep 2025 13:30:56 +0200 Subject: [PATCH 5/6] Java: Add new change note --- java/ql/lib/change-notes/2025-09-02-kdf-api.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2025-09-02-kdf-api.md diff --git a/java/ql/lib/change-notes/2025-09-02-kdf-api.md b/java/ql/lib/change-notes/2025-09-02-kdf-api.md new file mode 100644 index 000000000000..db812e907780 --- /dev/null +++ b/java/ql/lib/change-notes/2025-09-02-kdf-api.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added taint flow model for `java.crypto.KDF`. \ No newline at end of file From 424362a6cd88f5850f1ced014cd478f80008f0af Mon Sep 17 00:00:00 2001 From: idrissrio Date: Fri, 5 Sep 2025 16:03:11 +0200 Subject: [PATCH 6/6] Java: Address review comment. Fix dataflow model --- java/ql/lib/ext/javax.crypto.model.yml | 2 +- java/ql/lib/ext/javax.crypto.spec.model.yml | 14 +-- .../dataflow/kdf/KDFDataflowTest.java | 22 +++-- .../library-tests/dataflow/kdf/test.expected | 93 ++++++++++++++++++- .../test/library-tests/dataflow/kdf/test.ql | 27 +----- 5 files changed, 111 insertions(+), 47 deletions(-) diff --git a/java/ql/lib/ext/javax.crypto.model.yml b/java/ql/lib/ext/javax.crypto.model.yml index dfdbb3cc7033..0a2d43fce17f 100644 --- a/java/ql/lib/ext/javax.crypto.model.yml +++ b/java/ql/lib/ext/javax.crypto.model.yml @@ -18,7 +18,7 @@ extensions: - ["javax.crypto", "KDF", False, "getInstance", "(String,KDFParameters,Provider)", "", "Argument[0]", "ReturnValue.SyntheticField[javax.crypto.KDF.algorithm]", "value", "manual"] - ["javax.crypto", "KDF", False, "getInstance", "(String,KDFParameters,String)", "", "Argument[0]", "ReturnValue.SyntheticField[javax.crypto.KDF.algorithm]", "value", "manual"] - ["javax.crypto", "KDF", True, "getAlgorithm", "()", "", "Argument[this].SyntheticField[javax.crypto.KDF.algorithm]", "ReturnValue", "value", "manual"] - - ["javax.crypto", "KDF", True, "getProvider", "()", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["javax.crypto", "KDF", True, "getProvider", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["javax.crypto", "KDF", True, "deriveKey", "(String,AlgorithmParameterSpec)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - ["javax.crypto", "KDF", True, "deriveData", "(AlgorithmParameterSpec)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["javax.crypto", "SecretKey", True, "getEncoded", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/javax.crypto.spec.model.yml b/java/ql/lib/ext/javax.crypto.spec.model.yml index 02cb3494fbac..e670af7622ad 100644 --- a/java/ql/lib/ext/javax.crypto.spec.model.yml +++ b/java/ql/lib/ext/javax.crypto.spec.model.yml @@ -8,19 +8,15 @@ extensions: - ["javax.crypto.spec", "RC2ParameterSpec", True, "RC2ParameterSpec", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] - ["javax.crypto.spec", "RC5ParameterSpec", True, "RC5ParameterSpec", "", "", "Argument[3]", "Argument[this]", "taint", "manual"] - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(byte[])", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(byte[])", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(byte[])", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(SecretKey)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(SecretKey)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(SecretKey)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(SecretKey)", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(byte[])", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(byte[])", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(byte[])", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(SecretKey)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(SecretKey)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(SecretKey)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(SecretKey)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "thenExpand", "(byte[],int)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "thenExpand", "(byte[],int)", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "thenExpand", "(byte[],int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["javax.crypto.spec", "HKDFParameterSpec", False, "expandOnly", "(SecretKey,byte[],int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["javax.crypto.spec", "HKDFParameterSpec", False, "expandOnly", "(SecretKey,byte[],int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - ["javax.crypto.spec", "SecretKeySpec", False, "SecretKeySpec", "(byte[],String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] diff --git a/java/ql/test/library-tests/dataflow/kdf/KDFDataflowTest.java b/java/ql/test/library-tests/dataflow/kdf/KDFDataflowTest.java index 46885be1f4ca..984cdd702a2b 100644 --- a/java/ql/test/library-tests/dataflow/kdf/KDFDataflowTest.java +++ b/java/ql/test/library-tests/dataflow/kdf/KDFDataflowTest.java @@ -2,8 +2,14 @@ import javax.crypto.spec.HKDFParameterSpec; public class KDFDataflowTest { + public static String source(String label) { + return "tainted"; + } + + public static void sink(Object o) {} + public static void main(String[] args) throws Exception { - String userInput = args[0]; // source + String userInput = source(""); byte[] taintedBytes = userInput.getBytes(); testBuilderPattern(taintedBytes); @@ -20,7 +26,7 @@ public static void testBuilderPattern(byte[] taintedIKM) throws Exception { KDF kdf = KDF.getInstance("HKDF-SHA256"); byte[] result = kdf.deriveData(spec); - sink(result); // should flag + sink(result); // $ hasTaintFlow } public static void testSeparateBuilder(byte[] taintedIKM) throws Exception { @@ -30,11 +36,9 @@ public static void testSeparateBuilder(byte[] taintedIKM) throws Exception { KDF kdf = KDF.getInstance("HKDF-SHA256"); byte[] result = kdf.deriveData(spec); - sink(result); // should flag + sink(result); // $ hasTaintFlow } - public static void sink(Object o) {} - public static void testKDFWithSalt(byte[] taintedIKM) throws Exception { HKDFParameterSpec.Builder builder = HKDFParameterSpec.ofExtract(); builder.addIKM(taintedIKM); @@ -43,7 +47,7 @@ public static void testKDFWithSalt(byte[] taintedIKM) throws Exception { KDF kdf = KDF.getInstance("HKDF-SHA256"); byte[] result = kdf.deriveData(spec); - sink(result); // should flag + sink(result); // $ hasTaintFlow } public static void testStaticParameterSpec(byte[] taintedIKM) throws Exception { @@ -53,18 +57,18 @@ public static void testStaticParameterSpec(byte[] taintedIKM) throws Exception { KDF kdf = KDF.getInstance("HKDF-SHA256"); byte[] result = kdf.deriveData(spec); - sink(result); // should flag + sink(result); // $ hasTaintFlow } public static void testCleanUsage() throws Exception { byte[] cleanKeyMaterial = "static-key-material".getBytes(); HKDFParameterSpec.Builder builder = HKDFParameterSpec.ofExtract(); - builder.addIKM(cleanKeyMaterial); // clean input + builder.addIKM(cleanKeyMaterial); HKDFParameterSpec spec = builder.thenExpand("info".getBytes(), 32); KDF kdf = KDF.getInstance("HKDF-SHA256"); byte[] cleanResult = kdf.deriveData(spec); - sink(cleanResult); // should NOT flag - no taint source + sink(cleanResult); // Safe - no taint } } \ No newline at end of file diff --git a/java/ql/test/library-tests/dataflow/kdf/test.expected b/java/ql/test/library-tests/dataflow/kdf/test.expected index a53c17f410e9..f2e5841b7f38 100644 --- a/java/ql/test/library-tests/dataflow/kdf/test.expected +++ b/java/ql/test/library-tests/dataflow/kdf/test.expected @@ -1,4 +1,89 @@ -| KDFDataflowTest.java:6:28:6:34 | ...[...] | KDFDataflowTest.java:23:14:23:19 | result | -| KDFDataflowTest.java:6:28:6:34 | ...[...] | KDFDataflowTest.java:33:14:33:19 | result | -| KDFDataflowTest.java:6:28:6:34 | ...[...] | KDFDataflowTest.java:46:14:46:19 | result | -| KDFDataflowTest.java:6:28:6:34 | ...[...] | KDFDataflowTest.java:56:14:56:19 | result | \ No newline at end of file +models +| 1 | Summary: java.lang; String; false; getBytes; ; ; Argument[this]; ReturnValue; taint; manual | +| 2 | Summary: javax.crypto.spec; HKDFParameterSpec$Builder; true; addIKM; (byte[]); ; Argument[0]; Argument[this]; taint; manual | +| 3 | Summary: javax.crypto.spec; HKDFParameterSpec$Builder; true; addIKM; (byte[]); ; Argument[this]; ReturnValue; value; manual | +| 4 | Summary: javax.crypto.spec; HKDFParameterSpec$Builder; true; thenExpand; (byte[],int); ; Argument[this]; ReturnValue; taint; manual | +| 5 | Summary: javax.crypto.spec; HKDFParameterSpec; false; expandOnly; (SecretKey,byte[],int); ; Argument[0]; ReturnValue; taint; manual | +| 6 | Summary: javax.crypto.spec; SecretKeySpec; false; SecretKeySpec; (byte[],String); ; Argument[0]; Argument[this]; taint; manual | +| 7 | Summary: javax.crypto; KDF; true; deriveData; (AlgorithmParameterSpec); ; Argument[0]; ReturnValue; taint; manual | +edges +| KDFDataflowTest.java:12:28:12:37 | source(...) : String | KDFDataflowTest.java:13:31:13:39 | userInput : String | provenance | | +| KDFDataflowTest.java:13:31:13:39 | userInput : String | KDFDataflowTest.java:13:31:13:50 | getBytes(...) : byte[] | provenance | MaD:1 | +| KDFDataflowTest.java:13:31:13:50 | getBytes(...) : byte[] | KDFDataflowTest.java:15:28:15:39 | taintedBytes : byte[] | provenance | | +| KDFDataflowTest.java:13:31:13:50 | getBytes(...) : byte[] | KDFDataflowTest.java:16:29:16:40 | taintedBytes : byte[] | provenance | | +| KDFDataflowTest.java:13:31:13:50 | getBytes(...) : byte[] | KDFDataflowTest.java:17:25:17:36 | taintedBytes : byte[] | provenance | | +| KDFDataflowTest.java:13:31:13:50 | getBytes(...) : byte[] | KDFDataflowTest.java:18:33:18:44 | taintedBytes : byte[] | provenance | | +| KDFDataflowTest.java:15:28:15:39 | taintedBytes : byte[] | KDFDataflowTest.java:22:43:22:59 | taintedIKM : byte[] | provenance | | +| KDFDataflowTest.java:16:29:16:40 | taintedBytes : byte[] | KDFDataflowTest.java:32:44:32:60 | taintedIKM : byte[] | provenance | | +| KDFDataflowTest.java:17:25:17:36 | taintedBytes : byte[] | KDFDataflowTest.java:42:40:42:56 | taintedIKM : byte[] | provenance | | +| KDFDataflowTest.java:18:33:18:44 | taintedBytes : byte[] | KDFDataflowTest.java:53:48:53:64 | taintedIKM : byte[] | provenance | | +| KDFDataflowTest.java:22:43:22:59 | taintedIKM : byte[] | KDFDataflowTest.java:24:24:24:33 | taintedIKM : byte[] | provenance | | +| KDFDataflowTest.java:24:9:24:15 | builder [post update] : Builder | KDFDataflowTest.java:25:34:25:40 | builder : Builder | provenance | | +| KDFDataflowTest.java:24:24:24:33 | taintedIKM : byte[] | KDFDataflowTest.java:24:9:24:15 | builder [post update] : Builder | provenance | MaD:2 | +| KDFDataflowTest.java:25:34:25:40 | builder : Builder | KDFDataflowTest.java:25:34:25:74 | thenExpand(...) : ExtractThenExpand | provenance | MaD:4 | +| KDFDataflowTest.java:25:34:25:74 | thenExpand(...) : ExtractThenExpand | KDFDataflowTest.java:28:40:28:43 | spec : ExtractThenExpand | provenance | | +| KDFDataflowTest.java:28:25:28:44 | deriveData(...) : byte[] | KDFDataflowTest.java:29:14:29:19 | result | provenance | | +| KDFDataflowTest.java:28:40:28:43 | spec : ExtractThenExpand | KDFDataflowTest.java:28:25:28:44 | deriveData(...) : byte[] | provenance | MaD:7 | +| KDFDataflowTest.java:32:44:32:60 | taintedIKM : byte[] | KDFDataflowTest.java:34:62:34:71 | taintedIKM : byte[] | provenance | | +| KDFDataflowTest.java:34:46:34:72 | addIKM(...) : Builder | KDFDataflowTest.java:35:34:35:41 | builder2 : Builder | provenance | | +| KDFDataflowTest.java:34:62:34:71 | taintedIKM : byte[] | KDFDataflowTest.java:34:46:34:72 | addIKM(...) : Builder | provenance | MaD:2+MaD:3 | +| KDFDataflowTest.java:35:34:35:41 | builder2 : Builder | KDFDataflowTest.java:35:34:35:75 | thenExpand(...) : ExtractThenExpand | provenance | MaD:4 | +| KDFDataflowTest.java:35:34:35:75 | thenExpand(...) : ExtractThenExpand | KDFDataflowTest.java:38:40:38:43 | spec : ExtractThenExpand | provenance | | +| KDFDataflowTest.java:38:25:38:44 | deriveData(...) : byte[] | KDFDataflowTest.java:39:14:39:19 | result | provenance | | +| KDFDataflowTest.java:38:40:38:43 | spec : ExtractThenExpand | KDFDataflowTest.java:38:25:38:44 | deriveData(...) : byte[] | provenance | MaD:7 | +| KDFDataflowTest.java:42:40:42:56 | taintedIKM : byte[] | KDFDataflowTest.java:44:24:44:33 | taintedIKM : byte[] | provenance | | +| KDFDataflowTest.java:44:9:44:15 | builder [post update] : Builder | KDFDataflowTest.java:46:34:46:40 | builder : Builder | provenance | | +| KDFDataflowTest.java:44:24:44:33 | taintedIKM : byte[] | KDFDataflowTest.java:44:9:44:15 | builder [post update] : Builder | provenance | MaD:2 | +| KDFDataflowTest.java:46:34:46:40 | builder : Builder | KDFDataflowTest.java:46:34:46:74 | thenExpand(...) : ExtractThenExpand | provenance | MaD:4 | +| KDFDataflowTest.java:46:34:46:74 | thenExpand(...) : ExtractThenExpand | KDFDataflowTest.java:49:40:49:43 | spec : ExtractThenExpand | provenance | | +| KDFDataflowTest.java:49:25:49:44 | deriveData(...) : byte[] | KDFDataflowTest.java:50:14:50:19 | result | provenance | | +| KDFDataflowTest.java:49:40:49:43 | spec : ExtractThenExpand | KDFDataflowTest.java:49:25:49:44 | deriveData(...) : byte[] | provenance | MaD:7 | +| KDFDataflowTest.java:53:48:53:64 | taintedIKM : byte[] | KDFDataflowTest.java:54:89:54:98 | taintedIKM : byte[] | provenance | | +| KDFDataflowTest.java:54:53:54:106 | new SecretKeySpec(...) : SecretKeySpec | KDFDataflowTest.java:56:13:56:21 | secretKey : SecretKeySpec | provenance | | +| KDFDataflowTest.java:54:89:54:98 | taintedIKM : byte[] | KDFDataflowTest.java:54:53:54:106 | new SecretKeySpec(...) : SecretKeySpec | provenance | MaD:6 | +| KDFDataflowTest.java:55:34:56:45 | expandOnly(...) : Expand | KDFDataflowTest.java:59:40:59:43 | spec : Expand | provenance | | +| KDFDataflowTest.java:56:13:56:21 | secretKey : SecretKeySpec | KDFDataflowTest.java:55:34:56:45 | expandOnly(...) : Expand | provenance | MaD:5 | +| KDFDataflowTest.java:59:25:59:44 | deriveData(...) : byte[] | KDFDataflowTest.java:60:14:60:19 | result | provenance | | +| KDFDataflowTest.java:59:40:59:43 | spec : Expand | KDFDataflowTest.java:59:25:59:44 | deriveData(...) : byte[] | provenance | MaD:7 | +nodes +| KDFDataflowTest.java:12:28:12:37 | source(...) : String | semmle.label | source(...) : String | +| KDFDataflowTest.java:13:31:13:39 | userInput : String | semmle.label | userInput : String | +| KDFDataflowTest.java:13:31:13:50 | getBytes(...) : byte[] | semmle.label | getBytes(...) : byte[] | +| KDFDataflowTest.java:15:28:15:39 | taintedBytes : byte[] | semmle.label | taintedBytes : byte[] | +| KDFDataflowTest.java:16:29:16:40 | taintedBytes : byte[] | semmle.label | taintedBytes : byte[] | +| KDFDataflowTest.java:17:25:17:36 | taintedBytes : byte[] | semmle.label | taintedBytes : byte[] | +| KDFDataflowTest.java:18:33:18:44 | taintedBytes : byte[] | semmle.label | taintedBytes : byte[] | +| KDFDataflowTest.java:22:43:22:59 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] | +| KDFDataflowTest.java:24:9:24:15 | builder [post update] : Builder | semmle.label | builder [post update] : Builder | +| KDFDataflowTest.java:24:24:24:33 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] | +| KDFDataflowTest.java:25:34:25:40 | builder : Builder | semmle.label | builder : Builder | +| KDFDataflowTest.java:25:34:25:74 | thenExpand(...) : ExtractThenExpand | semmle.label | thenExpand(...) : ExtractThenExpand | +| KDFDataflowTest.java:28:25:28:44 | deriveData(...) : byte[] | semmle.label | deriveData(...) : byte[] | +| KDFDataflowTest.java:28:40:28:43 | spec : ExtractThenExpand | semmle.label | spec : ExtractThenExpand | +| KDFDataflowTest.java:29:14:29:19 | result | semmle.label | result | +| KDFDataflowTest.java:32:44:32:60 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] | +| KDFDataflowTest.java:34:46:34:72 | addIKM(...) : Builder | semmle.label | addIKM(...) : Builder | +| KDFDataflowTest.java:34:62:34:71 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] | +| KDFDataflowTest.java:35:34:35:41 | builder2 : Builder | semmle.label | builder2 : Builder | +| KDFDataflowTest.java:35:34:35:75 | thenExpand(...) : ExtractThenExpand | semmle.label | thenExpand(...) : ExtractThenExpand | +| KDFDataflowTest.java:38:25:38:44 | deriveData(...) : byte[] | semmle.label | deriveData(...) : byte[] | +| KDFDataflowTest.java:38:40:38:43 | spec : ExtractThenExpand | semmle.label | spec : ExtractThenExpand | +| KDFDataflowTest.java:39:14:39:19 | result | semmle.label | result | +| KDFDataflowTest.java:42:40:42:56 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] | +| KDFDataflowTest.java:44:9:44:15 | builder [post update] : Builder | semmle.label | builder [post update] : Builder | +| KDFDataflowTest.java:44:24:44:33 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] | +| KDFDataflowTest.java:46:34:46:40 | builder : Builder | semmle.label | builder : Builder | +| KDFDataflowTest.java:46:34:46:74 | thenExpand(...) : ExtractThenExpand | semmle.label | thenExpand(...) : ExtractThenExpand | +| KDFDataflowTest.java:49:25:49:44 | deriveData(...) : byte[] | semmle.label | deriveData(...) : byte[] | +| KDFDataflowTest.java:49:40:49:43 | spec : ExtractThenExpand | semmle.label | spec : ExtractThenExpand | +| KDFDataflowTest.java:50:14:50:19 | result | semmle.label | result | +| KDFDataflowTest.java:53:48:53:64 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] | +| KDFDataflowTest.java:54:53:54:106 | new SecretKeySpec(...) : SecretKeySpec | semmle.label | new SecretKeySpec(...) : SecretKeySpec | +| KDFDataflowTest.java:54:89:54:98 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] | +| KDFDataflowTest.java:55:34:56:45 | expandOnly(...) : Expand | semmle.label | expandOnly(...) : Expand | +| KDFDataflowTest.java:56:13:56:21 | secretKey : SecretKeySpec | semmle.label | secretKey : SecretKeySpec | +| KDFDataflowTest.java:59:25:59:44 | deriveData(...) : byte[] | semmle.label | deriveData(...) : byte[] | +| KDFDataflowTest.java:59:40:59:43 | spec : Expand | semmle.label | spec : Expand | +| KDFDataflowTest.java:60:14:60:19 | result | semmle.label | result | +subpaths +testFailures diff --git a/java/ql/test/library-tests/dataflow/kdf/test.ql b/java/ql/test/library-tests/dataflow/kdf/test.ql index 43534d2d3d8a..b2ffe7d9a679 100644 --- a/java/ql/test/library-tests/dataflow/kdf/test.ql +++ b/java/ql/test/library-tests/dataflow/kdf/test.ql @@ -1,24 +1,3 @@ -import java -import semmle.code.java.dataflow.TaintTracking - -module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node n) { - exists(ArrayAccess aa | - aa.getArray().(VarAccess).getVariable().hasName("args") and - n.asExpr() = aa - ) - } - - predicate isSink(DataFlow::Node n) { - exists(MethodCall ma | - ma.getMethod().hasName("sink") and - n.asExpr() = ma.getAnArgument() - ) - } -} - -module Flow = TaintTracking::Global; - -from DataFlow::Node src, DataFlow::Node sink -where Flow::flow(src, sink) -select src, sink +import utils.test.InlineFlowTest +import TaintFlowTest +import TaintFlow::PathGraph