Merge pull request #4579 from erik-krogh/redos

Approved by asgerf
This commit is contained in:
CodeQL CI
2020-11-05 08:38:44 +00:00
committed by GitHub
6 changed files with 219 additions and 8 deletions

View File

@@ -14,9 +14,15 @@
import javascript
import semmle.javascript.security.performance.PolynomialReDoS::PolynomialReDoS
import semmle.javascript.security.performance.SuperlinearBackTracking
import DataFlow::PathGraph
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
where
cfg.hasFlowPath(source, sink) and
not (
source.getNode().(Source).getKind() = "url" and
sink.getNode().(Sink).getRegExp().(PolynomialBackTrackingTerm).isAtEndLine()
)
select sink.getNode(), source, sink, "This expensive $@ use depends on $@.",
sink.getNode().(Sink).getRegExp(), "regular expression", source.getNode(), "a user-provided value"

View File

@@ -11,7 +11,13 @@ module PolynomialReDoS {
/**
* A data flow source node for polynomial regular expression denial-of-service vulnerabilities.
*/
abstract class Source extends DataFlow::Node { }
abstract class Source extends DataFlow::Node {
/**
* Gets the kind of source that is being accesed. See `HTTP::RequestInputAccess::getKind()`.
* Can be one of "parameter", "header", "body", "url", "cookie".
*/
abstract string getKind();
}
/**
* A data flow sink node for polynomial regular expression denial-of-service vulnerabilities.
@@ -31,6 +37,8 @@ module PolynomialReDoS {
*/
class RequestInputAccessAsSource extends Source {
RequestInputAccessAsSource() { this instanceof HTTP::RequestInputAccess }
override string getKind() { result = this.(HTTP::RequestInputAccess).getKind() }
}
/**

View File

@@ -124,10 +124,20 @@ class PolynomialBackTrackingTerm extends InfiniteRepetitionQuantifier {
forall(RegExpTerm pred | pred = this.getPredecessor+() | matchesEpsilon(pred)) and
reason = "it can start matching anywhere"
or
exists(InfiniteRepetitionQuantifier pred |
pred = getAMatchPredecessor(this.getPredecessor()) and
compatible(pred.getAChild(), this.getAChild())
exists(RegExpTerm pred |
pred instanceof InfiniteRepetitionQuantifier
or
forall(RegExpTerm predpred | predpred = pred.getPredecessor+() | matchesEpsilon(predpred))
|
pred = getAMatchPredecessor(this.getPredecessor()) and
(
// compatible children
compatible(pred.getAChild(), this.getAChild())
or
// or `this` is compatible with everything (and the predecessor is something)
unique( | | this.getAChild()) instanceof RegExpDot and
exists([pred, pred.getAChild()].getAMatchedString())
) and
reason =
"it can start matching anywhere after the start of the preceeding '" + pred.toString() +
"'"
@@ -136,6 +146,15 @@ class PolynomialBackTrackingTerm extends InfiniteRepetitionQuantifier {
not this.getParent*() instanceof RegExpSubPattern // too many corner cases
}
/**
* Holds if all non-empty successors to the polynomial backtracking term matches the end of the line.
*/
predicate isAtEndLine() {
forall(RegExpTerm succ | this.getSuccessor+() = succ and not matchesEpsilon(succ) |
succ instanceof RegExpDollar
)
}
/**
* Gets the reason for the number of match attempts.
*/

View File

@@ -12,12 +12,46 @@
| polynomial-redos.js:22:57:22:59 | \\d+ | it can start matching anywhere after the start of the preceeding '\\d*' |
| polynomial-redos.js:22:57:22:59 | \\d+ | it can start matching anywhere after the start of the preceeding '\\d+' |
| polynomial-redos.js:25:37:25:56 | [a-zA-Z0-9+\\/ \\t\\n]+ | it can start matching anywhere after the start of the preceeding '[ \\t]+' |
| polynomial-redos.js:25:63:25:64 | .* | it can start matching anywhere after the start of the preceeding '[=]*' |
| polynomial-redos.js:25:63:25:64 | .* | it can start matching anywhere after the start of the preceeding '[a-zA-Z0-9+\\/ \\t\\n]+' |
| polynomial-redos.js:27:14:27:22 | [A-Z]{2,} | it can start matching anywhere |
| polynomial-redos.js:30:19:30:22 | [?]+ | it can start matching anywhere |
| polynomial-redos.js:30:23:30:24 | .* | it can start matching anywhere after the start of the preceeding '[?]' |
| polynomial-redos.js:30:23:30:24 | .* | it can start matching anywhere after the start of the preceeding '[?]+' |
| polynomial-redos.js:31:42:31:43 | -+ | it can start matching anywhere |
| polynomial-redos.js:32:45:32:47 | \\n* | it can start matching anywhere |
| polynomial-redos.js:33:17:33:20 | (.)* | it can start matching anywhere |
| polynomial-redos.js:36:18:36:19 | .* | it can start matching anywhere after the start of the preceeding '<' |
| polynomial-redos.js:37:18:37:19 | .* | it can start matching anywhere after the start of the preceeding '<' |
| polynomial-redos.js:38:18:38:19 | .* | it can start matching anywhere after the start of the preceeding '<' |
| polynomial-redos.js:48:22:48:24 | \\s* | it can start matching anywhere |
| polynomial-redos.js:50:4:50:5 | .* | it can start matching anywhere after the start of the preceeding 'Y' |
| polynomial-redos.js:51:11:51:17 | (YH\|J)* | it can start matching anywhere after the start of the preceeding '(YH\|K)' |
| polynomial-redos.js:51:11:51:17 | (YH\|J)* | it can start matching anywhere after the start of the preceeding 'YH\|K' |
| polynomial-redos.js:52:12:52:13 | .* | it can start matching anywhere after the start of the preceeding '(YH\|K)' |
| polynomial-redos.js:52:12:52:13 | .* | it can start matching anywhere after the start of the preceeding 'K' |
| polynomial-redos.js:52:12:52:13 | .* | it can start matching anywhere after the start of the preceeding 'YH' |
| polynomial-redos.js:52:12:52:13 | .* | it can start matching anywhere after the start of the preceeding 'YH\|K' |
| polynomial-redos.js:53:3:53:8 | (B\|Y)+ | it can start matching anywhere |
| polynomial-redos.js:53:9:53:12 | (Y)* | it can start matching anywhere after the start of the preceeding '(B\|Y)' |
| polynomial-redos.js:53:9:53:12 | (Y)* | it can start matching anywhere after the start of the preceeding '(B\|Y)+' |
| polynomial-redos.js:53:9:53:12 | (Y)* | it can start matching anywhere after the start of the preceeding 'B\|Y' |
| polynomial-redos.js:54:4:54:9 | (B\|Y)+ | it can start matching anywhere |
| polynomial-redos.js:55:11:55:14 | (Y)* | it can start matching anywhere after the start of the preceeding '(B\|Y)+' |
| polynomial-redos.js:56:10:56:13 | (Y)* | it can start matching anywhere after the start of the preceeding '(B\|Y)+' |
| polynomial-redos.js:57:11:57:16 | (Y\|K)* | it can start matching anywhere after the start of the preceeding '(B\|Y)+' |
| polynomial-redos.js:58:11:58:12 | .* | it can start matching anywhere after the start of the preceeding '(B\|Y)+' |
| polynomial-redos.js:62:7:62:8 | Y* | it can start matching anywhere after the start of the preceeding 'Y*' |
| polynomial-redos.js:63:11:63:12 | Y* | it can start matching anywhere after the start of the preceeding '(K\|Y)+' |
| polynomial-redos.js:64:14:64:15 | Y* | it can start matching anywhere after the start of the preceeding '(K\|Y)+' |
| polynomial-redos.js:65:14:65:15 | .* | it can start matching anywhere after the start of the preceeding '(K\|Y)+' |
| polynomial-redos.js:66:9:66:10 | .* | it can start matching anywhere after the start of the preceeding '(K\|Y)' |
| polynomial-redos.js:66:9:66:10 | .* | it can start matching anywhere after the start of the preceeding 'K' |
| polynomial-redos.js:66:9:66:10 | .* | it can start matching anywhere after the start of the preceeding 'K\|Y' |
| polynomial-redos.js:66:9:66:10 | .* | it can start matching anywhere after the start of the preceeding 'Y' |
| polynomial-redos.js:67:8:67:9 | .* | it can start matching anywhere after the start of the preceeding '[^Y]' |
| polynomial-redos.js:68:8:68:9 | .* | it can start matching anywhere after the start of the preceeding '[^Y]' |
| polynomial-redos.js:69:8:69:9 | .* | it can start matching anywhere after the start of the preceeding '[^Y]' |
| regexplib/address.js:18:26:18:31 | [ \\w]* | it can start matching anywhere after the start of the preceeding '[ \\w]{3,}' |
| regexplib/address.js:20:144:20:147 | [ ]+ | it can start matching anywhere after the start of the preceeding '[a-zA-Z0-9 \\-.]{6,}' |
| regexplib/address.js:24:26:24:31 | [ \\w]* | it can start matching anywhere after the start of the preceeding '[ \\w]{3,}' |
@@ -36,7 +70,11 @@
| regexplib/address.js:75:631:75:635 | \\x20* | it can start matching anywhere after the start of the preceeding '\\x20*' |
| regexplib/address.js:75:796:75:798 | \\s+ | it can start matching anywhere after the start of the preceeding '\\s+' |
| regexplib/address.js:85:15:85:49 | ([0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,])+ | it can start matching anywhere |
| regexplib/address.js:85:51:85:67 | ([ ]\|[:]\|\\t\|[-])* | it can start matching anywhere after the start of the preceeding '([0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,])' |
| regexplib/address.js:85:51:85:67 | ([ ]\|[:]\|\\t\|[-])* | it can start matching anywhere after the start of the preceeding '([0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,])+' |
| regexplib/address.js:85:51:85:67 | ([ ]\|[:]\|\\t\|[-])* | it can start matching anywhere after the start of the preceeding '[0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,]' |
| regexplib/address.js:85:51:85:67 | ([ ]\|[:]\|\\t\|[-])* | it can start matching anywhere after the start of the preceeding '[ ]' |
| regexplib/address.js:85:51:85:67 | ([ ]\|[:]\|\\t\|[-])* | it can start matching anywhere after the start of the preceeding '[-]' |
| regexplib/address.js:93:3:93:5 | \\s* | it can start matching anywhere |
| regexplib/address.js:93:48:93:50 | \\s* | it can start matching anywhere |
| regexplib/address.js:93:93:93:95 | \\s* | it can start matching anywhere |
@@ -50,19 +88,28 @@
| regexplib/email.js:28:73:28:87 | [0-9a-zA-Z'\\.]+ | it can start matching anywhere |
| regexplib/email.js:28:125:28:139 | [0-9a-zA-Z'\\.]+ | it can start matching anywhere |
| regexplib/email.js:29:2:29:7 | [\\w-]+ | it can start matching anywhere |
| regexplib/markup.js:1:11:1:12 | .* | it can start matching anywhere after the start of the preceeding '<' |
| regexplib/markup.js:6:99:6:113 | [\\s\\w\\d\\)\\(\\,]* | it can start matching anywhere after the start of the preceeding '[\\d\\w]+' |
| regexplib/markup.js:11:6:11:8 | .*? | it can start matching anywhere after the start of the preceeding '<!--' |
| regexplib/markup.js:13:14:13:16 | .+? | it can start matching anywhere after the start of the preceeding '<' |
| regexplib/markup.js:14:10:14:11 | .* | it can start matching anywhere after the start of the preceeding '<' |
| regexplib/markup.js:14:13:14:14 | .* | it can start matching anywhere after the start of the preceeding '<' |
| regexplib/markup.js:19:2:19:12 | (<meta\\s+)* | it can start matching anywhere |
| regexplib/markup.js:20:155:20:156 | '+ | it can start matching anywhere after the start of the preceeding ''+' |
| regexplib/markup.js:20:197:20:198 | "+ | it can start matching anywhere after the start of the preceeding '"+' |
| regexplib/markup.js:37:15:37:19 | [\\w]* | it can start matching anywhere after the start of the preceeding '\\w+' |
| regexplib/markup.js:53:15:53:19 | [\\w]* | it can start matching anywhere after the start of the preceeding '\\w+' |
| regexplib/markup.js:62:35:62:37 | .*? | it can start matching anywhere after the start of the preceeding '[\\s\\"\\']+' |
| regexplib/markup.js:62:39:62:45 | [\\"\\']+ | it can start matching anywhere after the start of the preceeding '[\\s\\"\\']+' |
| regexplib/markup.js:62:46:62:48 | .*? | it can start matching anywhere after the start of the preceeding '[\\"\\']+' |
| regexplib/misc.js:76:2:76:27 | (AUX\|PRN\|NUL\|COM\\d\|LPT\\d)+ | it can start matching anywhere |
| regexplib/misc.js:83:15:83:17 | \\d* | it can start matching anywhere after the start of the preceeding '\\d*' |
| regexplib/misc.js:83:69:83:71 | \\d* | it can start matching anywhere after the start of the preceeding '\\d*' |
| regexplib/misc.js:93:3:93:4 | .* | it can start matching anywhere |
| regexplib/misc.js:95:25:95:26 | .+ | it can start matching anywhere after the start of the preceeding 'at\\s' |
| regexplib/misc.js:112:3:112:5 | \\s* | it can start matching anywhere |
| regexplib/misc.js:112:32:112:34 | \\s* | it can start matching anywhere |
| regexplib/misc.js:116:3:116:4 | .* | it can start matching anywhere after the start of the preceeding '{' |
| regexplib/misc.js:119:9:119:11 | \\s* | it can start matching anywhere |
| regexplib/misc.js:119:12:119:14 | \\(* | it can start matching anywhere |
| regexplib/misc.js:119:16:119:18 | \\s* | it can start matching anywhere |
@@ -114,13 +161,17 @@
| regexplib/strings.js:91:2:91:7 | (\\S*)+ | it can start matching anywhere |
| regexplib/strings.js:91:3:91:5 | \\S* | it can start matching anywhere |
| regexplib/uri.js:2:45:2:66 | [\\w\\-\\.,@?^=%&:/~\\+#]* | it can start matching anywhere after the start of the preceeding '[\\w\\-_]+' |
| regexplib/uri.js:5:42:5:43 | .* | it can start matching anywhere after the start of the preceeding '[\\w ]*' |
| regexplib/uri.js:13:69:13:102 | [a-zA-Z0-9\\-\\.\\?\\,\\'\\/\\\\\\+&%\\$#_]* | it can start matching anywhere after the start of the preceeding '[a-zA-Z0-9\\-\\._]+' |
| regexplib/uri.js:17:42:17:43 | .* | it can start matching anywhere after the start of the preceeding '[\\w ]*' |
| regexplib/uri.js:18:47:18:96 | ([ A-Za-z0-9'~` !@#$%&^_+=\\(\\){},\\-\\[\\];]\|([.]))*? | it can start matching anywhere after the start of the preceeding '([A-Za-z0-9'~`!@#$%&^_+=\\(\\){},\\-\\[\\]\\;])+?' |
| regexplib/uri.js:18:148:18:189 | ([A-Za-z0-9'~`!@#$%&^_+=\\(\\){},\\-\\[ \\];])+ | it can start matching anywhere after the start of the preceeding '[ A-Za-z0-9'~`!@#$ %&^_+=\\(\\){},\\-\\[\\]\\;]*?' |
| regexplib/uri.js:23:2:23:74 | (((file\|gopher\|news\|nntp\|telnet\|http\|ftp\|https\|ftps\|sftp):\\/\\/)\|(www\\.))+ | it can start matching anywhere |
| regexplib/uri.js:23:77:23:92 | [a-zA-Z0-9\\._-]+ | it can start matching anywhere after the start of the preceeding 'www\\.' |
| regexplib/uri.js:28:2:28:13 | [a-zA-Z]{3,} | it can start matching anywhere |
| regexplib/uri.js:29:2:29:45 | ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | it can start matching anywhere |
| regexplib/uri.js:34:3:34:9 | [^\\=&]+ | it can start matching anywhere |
| regexplib/uri.js:39:7:39:9 | .*? | it can start matching anywhere after the start of the preceeding '<a' |
| regexplib/uri.js:44:2:44:4 | .*? | it can start matching anywhere |
| regexplib/uri.js:53:3:53:9 | [^\\=&]+ | it can start matching anywhere |
| regexplib/uri.js:58:2:58:45 | ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | it can start matching anywhere |
@@ -129,8 +180,12 @@
| tst.js:14:13:14:18 | (.*,)+ | it can start matching anywhere |
| tst.js:14:14:14:15 | .* | it can start matching anywhere |
| tst.js:47:15:47:37 | (?:[^"']\|".*?"\|'.*?')*? | it can start matching anywhere |
| tst.js:47:25:47:27 | .*? | it can start matching anywhere after the start of the preceeding '"' |
| tst.js:47:31:47:33 | .*? | it can start matching anywhere after the start of the preceeding ''' |
| tst.js:66:15:66:44 | ([\\w#:.~>+()\\s-]+\|\\*\|\\[.*?\\])+ | it can start matching anywhere |
| tst.js:66:16:66:31 | [\\w#:.~>+()\\s-]+ | it can start matching anywhere |
| tst.js:66:38:66:40 | .*? | it can start matching anywhere after the start of the preceeding '\\[' |
| tst.js:66:46:66:48 | \\s* | it can start matching anywhere after the start of the preceeding '[\\w#:.~>+()\\s-]' |
| tst.js:66:46:66:48 | \\s* | it can start matching anywhere after the start of the preceeding '[\\w#:.~>+()\\s-]+' |
| tst.js:74:14:74:21 | (b\|a?b)* | it can start matching anywhere |
| tst.js:77:14:77:21 | (a\|aa?)* | it can start matching anywhere |

View File

@@ -28,8 +28,50 @@ nodes
| polynomial-redos.js:30:2:30:8 | tainted |
| polynomial-redos.js:33:2:33:8 | tainted |
| polynomial-redos.js:33:2:33:8 | tainted |
| polynomial-redos.js:36:2:36:8 | tainted |
| polynomial-redos.js:36:2:36:8 | tainted |
| polynomial-redos.js:37:2:37:8 | tainted |
| polynomial-redos.js:37:2:37:8 | tainted |
| polynomial-redos.js:38:2:38:8 | tainted |
| polynomial-redos.js:38:2:38:8 | tainted |
| polynomial-redos.js:48:2:48:8 | tainted |
| polynomial-redos.js:48:2:48:8 | tainted |
| polynomial-redos.js:50:14:50:20 | tainted |
| polynomial-redos.js:50:14:50:20 | tainted |
| polynomial-redos.js:51:26:51:32 | tainted |
| polynomial-redos.js:51:26:51:32 | tainted |
| polynomial-redos.js:52:22:52:28 | tainted |
| polynomial-redos.js:52:22:52:28 | tainted |
| polynomial-redos.js:53:21:53:27 | tainted |
| polynomial-redos.js:53:21:53:27 | tainted |
| polynomial-redos.js:54:22:54:28 | tainted |
| polynomial-redos.js:54:22:54:28 | tainted |
| polynomial-redos.js:55:23:55:29 | tainted |
| polynomial-redos.js:55:23:55:29 | tainted |
| polynomial-redos.js:56:22:56:28 | tainted |
| polynomial-redos.js:56:22:56:28 | tainted |
| polynomial-redos.js:57:25:57:31 | tainted |
| polynomial-redos.js:57:25:57:31 | tainted |
| polynomial-redos.js:58:21:58:27 | tainted |
| polynomial-redos.js:58:21:58:27 | tainted |
| polynomial-redos.js:62:17:62:23 | tainted |
| polynomial-redos.js:62:17:62:23 | tainted |
| polynomial-redos.js:63:21:63:27 | tainted |
| polynomial-redos.js:63:21:63:27 | tainted |
| polynomial-redos.js:64:24:64:30 | tainted |
| polynomial-redos.js:64:24:64:30 | tainted |
| polynomial-redos.js:65:24:65:30 | tainted |
| polynomial-redos.js:65:24:65:30 | tainted |
| polynomial-redos.js:66:19:66:25 | tainted |
| polynomial-redos.js:66:19:66:25 | tainted |
| polynomial-redos.js:67:18:67:24 | tainted |
| polynomial-redos.js:67:18:67:24 | tainted |
| polynomial-redos.js:68:18:68:24 | req.url |
| polynomial-redos.js:68:18:68:24 | req.url |
| polynomial-redos.js:68:18:68:24 | req.url |
| polynomial-redos.js:69:18:69:25 | req.body |
| polynomial-redos.js:69:18:69:25 | req.body |
| polynomial-redos.js:69:18:69:25 | req.body |
edges
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted |
@@ -57,10 +99,48 @@ edges
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:30:2:30:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:33:2:33:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:33:2:33:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:36:2:36:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:36:2:36:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:37:2:37:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:37:2:37:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:38:2:38:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:38:2:38:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:48:2:48:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:48:2:48:8 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:50:14:50:20 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:50:14:50:20 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:51:26:51:32 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:51:26:51:32 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:52:22:52:28 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:52:22:52:28 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:53:21:53:27 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:53:21:53:27 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:54:22:54:28 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:54:22:54:28 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:55:23:55:29 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:55:23:55:29 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:56:22:56:28 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:56:22:56:28 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:57:25:57:31 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:57:25:57:31 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:58:21:58:27 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:58:21:58:27 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:62:17:62:23 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:62:17:62:23 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:63:21:63:27 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:63:21:63:27 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:64:24:64:30 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:64:24:64:30 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:65:24:65:30 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:65:24:65:30 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:66:19:66:25 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:66:19:66:25 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:67:18:67:24 | tainted |
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:67:18:67:24 | tainted |
| polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:5:6:5:32 | tainted |
| polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:5:6:5:32 | tainted |
| polynomial-redos.js:68:18:68:24 | req.url | polynomial-redos.js:68:18:68:24 | req.url |
| polynomial-redos.js:69:18:69:25 | req.body | polynomial-redos.js:69:18:69:25 | req.body |
#select
| polynomial-redos.js:7:2:7:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:7:2:7:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:7:24:7:26 | \\s+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:8:2:8:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:8:2:8:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:8:17:8:18 | * | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
@@ -73,7 +153,29 @@ edges
| polynomial-redos.js:19:2:19:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:19:2:19:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:19:17:19:22 | [0-9]* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:20:2:20:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:20:2:20:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:20:56:20:58 | \\d+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:25:2:25:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:25:2:25:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:25:37:25:56 | [a-zA-Z0-9+\\/ \\t\\n]+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:25:2:25:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:25:2:25:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:25:63:25:64 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:27:77:27:83 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:27:77:27:83 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:27:14:27:22 | [A-Z]{2,} | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:30:2:30:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:30:2:30:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:30:19:30:22 | [?]+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:30:2:30:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:30:2:30:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:30:23:30:24 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:33:2:33:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:33:2:33:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:33:17:33:20 | (.)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:36:2:36:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:36:2:36:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:36:18:36:19 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:37:2:37:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:37:2:37:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:37:18:37:19 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:38:2:38:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:38:2:38:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:38:18:38:19 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:48:2:48:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:48:2:48:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:48:22:48:24 | \\s* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:50:14:50:20 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:50:14:50:20 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:50:4:50:5 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:51:26:51:32 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:51:26:51:32 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:51:11:51:17 | (YH\|J)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:52:22:52:28 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:52:22:52:28 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:52:12:52:13 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:53:21:53:27 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:53:21:53:27 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:53:3:53:8 | (B\|Y)+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:53:21:53:27 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:53:21:53:27 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:53:9:53:12 | (Y)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:54:22:54:28 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:54:22:54:28 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:54:4:54:9 | (B\|Y)+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:55:23:55:29 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:55:23:55:29 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:55:11:55:14 | (Y)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:56:22:56:28 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:56:22:56:28 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:56:10:56:13 | (Y)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:57:25:57:31 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:57:25:57:31 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:57:11:57:16 | (Y\|K)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:58:21:58:27 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:58:21:58:27 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:58:11:58:12 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:62:17:62:23 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:62:17:62:23 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:62:7:62:8 | Y* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:63:21:63:27 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:63:21:63:27 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:63:11:63:12 | Y* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:64:24:64:30 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:64:24:64:30 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:64:14:64:15 | Y* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:65:24:65:30 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:65:24:65:30 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:65:14:65:15 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:66:19:66:25 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:66:19:66:25 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:66:9:66:10 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:67:18:67:24 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:67:18:67:24 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:67:8:67:9 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:69:18:69:25 | req.body | polynomial-redos.js:69:18:69:25 | req.body | polynomial-redos.js:69:18:69:25 | req.body | This expensive $@ use depends on $@. | polynomial-redos.js:69:8:69:9 | .* | regular expression | polynomial-redos.js:69:18:69:25 | req.body | a user-provided value |

View File

@@ -33,9 +33,9 @@ app.use(function(req, res) {
tainted.match(/(.)*solve\/challenges\/server-side(.)*/); // NOT OK
tainted.match(/<head>(?![\s\S]*<head>)/i); // OK
tainted.match(/<.*class="([^"]+)".*>/); // NOT OK - but not flagged
tainted.match(/<.*style="([^"]+)".*>/); // NOT OK - but not flagged
tainted.match(/<.*href="([^"]+)".*>/); // NOT OK - but not flagged
tainted.match(/<.*class="([^"]+)".*>/); // NOT OK
tainted.match(/<.*style="([^"]+)".*>/); // NOT OK
tainted.match(/<.*href="([^"]+)".*>/); // NOT OK
tainted.match(/^([^-]+)-([A-Za-z0-9+/]+(?:=?=?))([?\x21-\x7E]*)$/); // NOT OK - but not flagged
tainted.match(/^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/); // NOT OK (it is a fix for the above, but it introduces exponential complexity elsewhere)
@@ -46,4 +46,25 @@ app.use(function(req, res) {
tainted.match(/^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)+$/); // NOT OK - but not flagged
tainted.match(/^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/); // OK
tainted.replaceAll(/\s*\n\s*/g, ' '); // NOT OK
/Y.*X/.test(tainted); // NOT OK
/B?(YH|K)(YH|J)*X/.test(tainted) // NOT OK
(/B?(YH|K).*X/.test(tainted)); // NOT OK
/(B|Y)+(Y)*X/.test(tainted) // NOT OK
(/(B|Y)+(.)*X/.test(tainted)) // NOT OK
(/f(B|Y)+(Y)*X/.test(tainted)); // NOT OK
/f(B|Y)+(Y)*X/.test(tainted) // NOT OK
(/f(B|Y)+(Y|K)*X/.test(tainted)) // NOT OK
(/f(B|Y)+.*X/.test(tainted)) // NOT OK
(/f(B|Y)+(.)*X/.test(tainted)) // NOT OK - but not flagged
(/^(.)*X/.test(tainted)); // OK
(/^Y(Y)*X/.test(tainted)); // OK
(/^Y*Y*X/.test(tainted)); // NOT OK
(/^(K|Y)+Y*X/.test(tainted)); // NOT OK
(/^foo(K|Y)+Y*X/.test(tainted)); // NOT OK
(/^foo(K|Y)+.*X/.test(tainted)); // NOT OK
(/(K|Y).*X/.test(tainted)); // NOT OK
(/[^Y].*X/.test(tainted)); // NOT OK
(/[^Y].*$/.test(req.url)); // OK - the input cannot contain newlines.
(/[^Y].*$/.test(req.body)); // NOT OK
});