Skip to content

Commit d955dce

Browse files
committed
Improve source of randomness detection
Also sanitize flow out of sinks to avoid overlapping paths
1 parent fc45621 commit d955dce

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

java/ql/lib/semmle/code/java/security/InsecureRandomnessQuery.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ abstract class InsecureRandomnessSource extends DataFlow::Node { }
2020
private class RandomMethodSource extends InsecureRandomnessSource {
2121
RandomMethodSource() {
2222
exists(RandomDataSource s | this.asExpr() = s.getOutput() |
23-
not s.getQualifier().getType() instanceof SafeRandomImplementation
23+
not s.getSourceOfRandomness() instanceof SafeRandomImplementation
2424
)
2525
}
2626
}
@@ -69,6 +69,8 @@ module InsecureRandomnessConfig implements DataFlow::ConfigSig {
6969

7070
predicate isBarrierIn(DataFlow::Node n) { isSource(n) }
7171

72+
predicate isBarrierOut(DataFlow::Node n) { isSink(n) }
73+
7274
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
7375
n1.asExpr() = n2.asExpr().(BinaryExpr).getAnOperand()
7476
or

java/ql/lib/semmle/code/java/security/RandomDataSource.qll

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
import java
6+
private import semmle.code.java.dataflow.TypeFlow
67

78
/**
89
* A method access that returns random data or writes random data to an argument.
@@ -43,6 +44,9 @@ abstract class RandomDataSource extends MethodCall {
4344
* in the case where it writes random data to that argument.
4445
*/
4546
abstract Expr getOutput();
47+
48+
/** Gets the type of the source of randomness used by this call. */
49+
RefType getSourceOfRandomness() { boundOrStaticType(this.getQualifier(), result) }
4650
}
4751

4852
/**
@@ -167,4 +171,18 @@ class ApacheCommonsRandomStringSource extends RandomDataSource {
167171
}
168172

169173
override Expr getOutput() { result = this }
174+
175+
override RefType getSourceOfRandomness() {
176+
if
177+
this.getMethod().hasStringSignature("random(int, int, int, boolean, boolean, char[], Random)")
178+
then boundOrStaticType(this.getArgument(6), result)
179+
else result.hasQualifiedName("java.util", "Random")
180+
}
181+
}
182+
183+
/** Holds if `t` is the static type of `e`, or an upper bound of the runtime type of `e`. */
184+
private predicate boundOrStaticType(Expr e, RefType t) {
185+
exprTypeFlow(e, t, false)
186+
or
187+
t = e.getType()
170188
}

0 commit comments

Comments
 (0)