Skip to content

Commit 85286f3

Browse files
committed
Java: Replace global flow by local flow
1 parent 722bd4d commit 85286f3

File tree

1 file changed

+31
-34
lines changed

1 file changed

+31
-34
lines changed

java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.ql

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -106,45 +106,42 @@ private predicate isEqualsIgnoreCaseMethodAccess(MethodAccess ma) {
106106
ma.getMethod().getDeclaringType() instanceof TypeString
107107
}
108108

109-
/** A configuration to model the flow of feature flags into `Guard`s. This is used to determine whether something is guarded by such a flag. */
110-
private class FlagToGuardFlow extends DataFlow::Configuration {
111-
FlagToGuardFlow() { this = "FlagToGuardFlow" }
112-
113-
override predicate isSource(DataFlow::Node source) {
114-
exists(VarAccess v | v.getVariable().getName() = getAFlagName() |
115-
source.asExpr() = v and v.getType() instanceof FlagType
116-
)
117-
or
118-
exists(StringLiteral s | s.getRepresentedString() = getAFlagName() | source.asExpr() = s)
119-
or
120-
exists(MethodAccess ma | ma.getMethod().getName() = getAFlagName() |
121-
source.asExpr() = ma and
122-
ma.getType() instanceof FlagType and
123-
not isEqualsIgnoreCaseMethodAccess(ma)
124-
)
125-
}
126-
127-
override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof Guard }
109+
/** Holds if `source` should is considered a flag. */
110+
private predicate isFlag(DataFlow::Node source) {
111+
exists(VarAccess v | v.getVariable().getName() = getAFlagName() |
112+
source.asExpr() = v and v.getType() instanceof FlagType
113+
)
114+
or
115+
exists(StringLiteral s | s.getRepresentedString() = getAFlagName() | source.asExpr() = s)
116+
or
117+
exists(MethodAccess ma | ma.getMethod().getName() = getAFlagName() |
118+
source.asExpr() = ma and
119+
ma.getType() instanceof FlagType and
120+
not isEqualsIgnoreCaseMethodAccess(ma)
121+
)
122+
}
128123

129-
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
130-
exists(MethodAccess ma | ma.getMethod() = any(EnvReadMethod m) |
131-
ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr()
132-
)
133-
or
134-
exists(MethodAccess ma |
135-
ma.getMethod().hasName("parseBoolean") and
136-
ma.getMethod().getDeclaringType().hasQualifiedName("java.lang", "Boolean")
137-
|
138-
ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr()
139-
)
140-
}
124+
/** Holds if there is flow from `node1` to `node2` either due to local flow or due to custom flow steps. */
125+
private predicate flagFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
126+
DataFlow::localFlowStep(node1, node2)
127+
or
128+
exists(MethodAccess ma | ma.getMethod() = any(EnvReadMethod m) |
129+
ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr()
130+
)
131+
or
132+
exists(MethodAccess ma |
133+
ma.getMethod().hasName("parseBoolean") and
134+
ma.getMethod().getDeclaringType().hasQualifiedName("java.lang", "Boolean")
135+
|
136+
ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr()
137+
)
141138
}
142139

143140
/** Gets a guard that depends on a flag. */
144141
private Guard getAGuard() {
145-
exists(FlagToGuardFlow cfg, DataFlow::Node source, DataFlow::Node sink |
146-
cfg.hasFlow(source, sink)
147-
|
142+
exists(DataFlow::Node source, DataFlow::Node sink |
143+
isFlag(source) and
144+
flagFlowStep*(source, sink) and
148145
sink.asExpr() = result
149146
)
150147
}

0 commit comments

Comments
 (0)