Skip to content

Commit 833c5ed

Browse files
Jami CogswellJami Cogswell
authored andcommitted
move to .qll file and switch to InlineExpectations tests
1 parent 25436fe commit 833c5ed

File tree

7 files changed

+114
-175
lines changed

7 files changed

+114
-175
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import java
2+
import semmle.code.java.dataflow.FlowSources
3+
import semmle.code.java.dataflow.TaintTracking
4+
5+
/**
6+
* A data flow sink for untrusted user input used to construct regular expressions.
7+
*/
8+
class RegexSink extends DataFlow::ExprNode {
9+
RegexSink() {
10+
exists(MethodAccess ma, Method m | m = ma.getMethod() |
11+
(
12+
m.getDeclaringType() instanceof TypeString and
13+
(
14+
ma.getArgument(0) = this.asExpr() and
15+
// TODO: confirm if more/less than the below need to be handled
16+
m.hasName(["matches", "split", "replaceFirst", "replaceAll"])
17+
)
18+
or
19+
// TODO: review Java Pattern API
20+
m.getDeclaringType().hasQualifiedName("java.util.regex", "Pattern") and
21+
(
22+
ma.getArgument(0) = this.asExpr() and
23+
// TODO: confirm if more/less than the below need to be handled
24+
m.hasName(["compile", "matches"])
25+
)
26+
or
27+
// TODO: read docs about regex APIs in Java
28+
m.getDeclaringType().hasQualifiedName("org.apache.commons.lang3", "RegExUtils") and
29+
(
30+
ma.getArgument(1) = this.asExpr() and
31+
m.getParameterType(1) instanceof TypeString and
32+
// TODO: confirm if more/less than the below need to be handled
33+
m.hasName([
34+
"removeAll", "removeFirst", "removePattern", "replaceAll", "replaceFirst",
35+
"replacePattern"
36+
])
37+
)
38+
)
39+
)
40+
}
41+
}
42+
43+
// TODO: is this abstract class needed? Are there pre-existing sanitizer classes that can be used instead?
44+
abstract class Sanitizer extends DataFlow::ExprNode { }
45+
46+
/**
47+
* A call to a function whose name suggests that it escapes regular
48+
* expression meta-characters.
49+
*/
50+
class RegExpSanitizationCall extends Sanitizer {
51+
RegExpSanitizationCall() {
52+
exists(string calleeName, string sanitize, string regexp |
53+
calleeName = this.asExpr().(Call).getCallee().getName() and
54+
sanitize = "(?:escape|saniti[sz]e)" and // TODO: confirm this is sufficient
55+
regexp = "regexp?" // TODO: confirm this is sufficient
56+
|
57+
calleeName
58+
.regexpMatch("(?i)(" + sanitize + ".*" + regexp + ".*)" + "|(" + regexp + ".*" + sanitize +
59+
".*)") // TODO: confirm this is sufficient
60+
)
61+
}
62+
}
63+
64+
/**
65+
* A taint-tracking configuration for untrusted user input used to construct regular expressions.
66+
*/
67+
class RegexInjectionConfiguration extends TaintTracking::Configuration {
68+
RegexInjectionConfiguration() { this = "RegexInjectionConfiguration" }
69+
70+
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
71+
72+
override predicate isSink(DataFlow::Node sink) { sink instanceof RegexSink }
73+
74+
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
75+
}

java/ql/src/Security/CWE/CWE-730/RegexInjection.ql

Lines changed: 1 addition & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -13,93 +13,10 @@
1313
*/
1414

1515
import java
16-
import semmle.code.java.dataflow.FlowSources
17-
import semmle.code.java.dataflow.TaintTracking
16+
import semmle.code.java.security.RegexInjectionQuery
1817
import DataFlow::PathGraph
1918

20-
/**
21-
* A data flow sink for untrusted user input used to construct regular expressions.
22-
*/
23-
class RegexSink extends DataFlow::ExprNode {
24-
RegexSink() {
25-
exists(MethodAccess ma, Method m | m = ma.getMethod() |
26-
(
27-
m.getDeclaringType() instanceof TypeString and
28-
(
29-
ma.getArgument(0) = this.asExpr() and
30-
// TODO: confirm if more/less than the below need to be handled
31-
m.hasName(["matches", "split", "replaceFirst", "replaceAll"])
32-
)
33-
or
34-
// TODO: review Java Pattern API
35-
m.getDeclaringType().hasQualifiedName("java.util.regex", "Pattern") and
36-
(
37-
ma.getArgument(0) = this.asExpr() and
38-
// TODO: confirm if more/less than the below need to be handled
39-
m.hasName(["compile", "matches"])
40-
)
41-
or
42-
// TODO: read docs about regex APIs in Java
43-
m.getDeclaringType().hasQualifiedName("org.apache.commons.lang3", "RegExUtils") and
44-
(
45-
ma.getArgument(1) = this.asExpr() and
46-
m.getParameterType(1) instanceof TypeString and
47-
// TODO: confirm if more/less than the below need to be handled
48-
m.hasName([
49-
"removeAll", "removeFirst", "removePattern", "replaceAll", "replaceFirst",
50-
"replacePattern"
51-
])
52-
)
53-
)
54-
)
55-
}
56-
}
57-
58-
// TODO: is this abstract class needed? Are there pre-existing sanitizer classes that can be used instead?
59-
abstract class Sanitizer extends DataFlow::ExprNode { }
60-
61-
/**
62-
* A call to a function whose name suggests that it escapes regular
63-
* expression meta-characters.
64-
*/
65-
class RegExpSanitizationCall extends Sanitizer {
66-
RegExpSanitizationCall() {
67-
exists(string calleeName, string sanitize, string regexp |
68-
calleeName = this.asExpr().(Call).getCallee().getName() and
69-
sanitize = "(?:escape|saniti[sz]e)" and // TODO: confirm this is sufficient
70-
regexp = "regexp?" // TODO: confirm this is sufficient
71-
|
72-
calleeName
73-
.regexpMatch("(?i)(" + sanitize + ".*" + regexp + ".*)" + "|(" + regexp + ".*" + sanitize +
74-
".*)") // TODO: confirm this is sufficient
75-
)
76-
}
77-
}
78-
79-
/**
80-
* A taint-tracking configuration for untrusted user input used to construct regular expressions.
81-
*/
82-
class RegexInjectionConfiguration extends TaintTracking::Configuration {
83-
RegexInjectionConfiguration() { this = "RegexInjectionConfiguration" }
84-
85-
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
86-
87-
override predicate isSink(DataFlow::Node sink) { sink instanceof RegexSink }
88-
89-
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
90-
}
91-
9219
from DataFlow::PathNode source, DataFlow::PathNode sink, RegexInjectionConfiguration c
9320
where c.hasFlowPath(source, sink)
9421
select sink.getNode(), source, sink, "This regular expression is constructed from a $@.",
9522
source.getNode(), "user-provided value"
96-
// from MethodAccess ma
97-
// where
98-
// // ma.getMethod().hasName("startsWith") and // graphhopper
99-
// // ma.getFile().getBaseName() = "NavigateResource.java" // graphhopper
100-
// // ma.getMethod().hasName("substring") and // jfinal
101-
// // ma.getFile().getBaseName() = "FileManager.java" // jfinal
102-
// ma.getMethod().hasName("startsWith") and // roller
103-
// ma.getFile().getBaseName() = "PageServlet.java" // roller (or RegexUtil.java)
104-
// ProteinArraySignificanceTestJSON.java or MockRKeys.java for cbioportal
105-
// select ma, "method access"

java/ql/test/query-tests/security/CWE-730/RegexInjection.expected

Lines changed: 0 additions & 73 deletions
This file was deleted.

java/ql/test/query-tests/security/CWE-730/RegexInjection.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.

java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.expected

Whitespace-only changes.

0 commit comments

Comments
 (0)