Split PolynomialRedos definition into a library to avoid duplication in the tests

This commit is contained in:
Joe Farebrother
2022-03-16 13:30:06 +00:00
parent c1290d9e2b
commit 6794268a3c
3 changed files with 43 additions and 59 deletions

View File

@@ -0,0 +1,34 @@
/** Definitions and configurations for the Polynomial ReDos query */
import semmle.code.java.security.performance.SuperlinearBackTracking
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.regex.RegexTreeView
import semmle.code.java.regex.RegexFlowConfigs
import semmle.code.java.dataflow.FlowSources
/** A sink for polynomial redos queries, where a regex is matched. */
class PolynomialRedosSink extends DataFlow::Node {
RegExpLiteral reg;
PolynomialRedosSink() { regexMatchedAgainst(reg.getRegex(), this.asExpr()) }
/** Gets the regex that is matched against this node. */
RegExpTerm getRegExp() { result.getParent() = reg }
}
/** A configuration for Polynomial ReDoS queries. */
class PolynomialRedosConfig extends TaintTracking::Configuration {
PolynomialRedosConfig() { this = "PolynomialRedosConfig" }
override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof PolynomialRedosSink }
}
/** Holds if there is flow from `source` to `sink` that is matched against the regexp term `regexp` that is vulnerable to Polynomial ReDoS. */
predicate hasPolynomialReDosResult(
DataFlow::PathNode source, DataFlow::PathNode sink, PolynomialBackTrackingTerm regexp
) {
any(PolynomialRedosConfig config).hasFlowPath(source, sink) and
regexp.getRootTerm() = sink.getNode().(PolynomialRedosSink).getRegExp()
}

View File

@@ -12,37 +12,12 @@
*/
import java
import semmle.code.java.security.performance.SuperlinearBackTracking
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.regex.RegexTreeView
import semmle.code.java.regex.RegexFlowConfigs
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.performance.PolynomialReDosQuery
import DataFlow::PathGraph
class PolynomialRedosSink extends DataFlow::Node {
RegExpLiteral reg;
PolynomialRedosSink() { regexMatchedAgainst(reg.getRegex(), this.asExpr()) }
RegExpTerm getRegExp() { result.getParent() = reg }
}
class PolynomialRedosConfig extends TaintTracking::Configuration {
PolynomialRedosConfig() { this = "PolynomialRedosConfig" }
override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof PolynomialRedosSink }
}
from
PolynomialRedosConfig config, DataFlow::PathNode source, DataFlow::PathNode sink,
PolynomialRedosSink sinkNode, PolynomialBackTrackingTerm regexp
where
config.hasFlowPath(source, sink) and
sinkNode = sink.getNode() and
regexp.getRootTerm() = sinkNode.getRegExp()
select sinkNode, source, sink,
from DataFlow::PathNode source, DataFlow::PathNode sink, PolynomialBackTrackingTerm regexp
where hasPolynomialReDosResult(source, sink, regexp)
select sink, source, sink,
"This $@ that depends on $@ may run slow on strings " + regexp.getPrefixMessage() +
"with many repetitions of '" + regexp.getPumpString() + "'.", regexp, "regular expression",
source.getNode(), "a user-provided value"

View File

@@ -1,26 +1,6 @@
import java
import TestUtilities.InlineExpectationsTest
import semmle.code.java.security.performance.SuperlinearBackTracking
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.regex.RegexTreeView
import semmle.code.java.regex.RegexFlowConfigs
import semmle.code.java.dataflow.FlowSources
class PolynomialRedosSink extends DataFlow::Node {
RegExpLiteral reg;
PolynomialRedosSink() { regexMatchedAgainst(reg.getRegex(), this.asExpr()) }
RegExpTerm getRegExp() { result.getParent() = reg }
}
class PolynomialRedosConfig extends TaintTracking::Configuration {
PolynomialRedosConfig() { this = "PolynomialRedosConfig" }
override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof PolynomialRedosSink }
}
import semmle.code.java.security.performance.PolynomialReDosQuery
class HasPolyRedos extends InlineExpectationsTest {
HasPolyRedos() { this = "HasPolyRedos" }
@@ -29,15 +9,10 @@ class HasPolyRedos extends InlineExpectationsTest {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "hasPolyRedos" and
exists(
PolynomialRedosConfig config, DataFlow::PathNode source, DataFlow::PathNode sink,
PolynomialRedosSink sinkNode, PolynomialBackTrackingTerm regexp
|
config.hasFlowPath(source, sink) and
sinkNode = sink.getNode() and
regexp.getRootTerm() = sinkNode.getRegExp() and
location = sinkNode.getLocation() and
element = sinkNode.toString() and
exists(DataFlow::PathNode source, DataFlow::PathNode sink, PolynomialBackTrackingTerm regexp |
hasPolynomialReDosResult(source, sink, regexp) and
location = sink.getNode().getLocation() and
element = sink.getNode().toString() and
value = ""
)
}