Closed ColdFire87 closed 4 years ago
INVALID
My lab machine has been repurposed so I don't think the web server is working.
So I used Docker instead to build the image locally, then run it against a regex pattern for validating a JWT.
Glad this worked!
Is the regex vulnerable but the wuestholz-RegexCheck detector couldn't provide an example of an evil input?
Wuestholz thinks it's vulnerable, but my tool couldn't parse Wuestholz's output.
Is the regex safe?
Yes. This is a false positive from Wuestholz. (Weideman is more trustworthy in my experience.)
Your regex has no ambiguity -- at each point in the pattern, when the regex engine encounters a character it has no choice about how to parse it.
.
, it must advanceIf your custom character classes included a .
as one of the valid characters, your regex would have ambiguity. While in one of the char classes with a .
, when the regex engine saw a .
it would have a choice about whether to consume it in the char class or to advance to the adjacent char class. This would give your regex polynomial worst-case time complexity on malicious input.
Here's an example of such a regex:
{"pattern": "^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$", "validateVuln_language": "javascript", "validateVuln_nPumps": 100000, "validateVuln_timeLimit": 2, "useCache": 0}
(Same as your original regex, but I added a .
to each character class).
(12:36:46) jamie@woody ~/Desktop/floss/vuln-regex-detector $ ./bin/check-regex.pl /tmp/reg.json
Config says to use the cache
Config says useCache 1
Query says I should not use the cache
Using default for detectVuln_memoryLimit: 8192
Using default for detectVuln_timeLimit: 60
Querying detectors
/home/jamie/Desktop/floss/vuln-regex-detector/src/detect/detect-vuln.pl /tmp/check-regex-12252.json 2>>/tmp/check-regex-12252-progress.log
Detectors said: {"pattern":"^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$","detectorOpinions":[{"patternVariant":"^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$","opinion":{"canAnalyze":0,"isSafe":"UNKNOWN"},"hasOpinion":1,"secToDecide":"0.0211","name":"rathnayake-rxxr2"},{"hasOpinion":1,"secToDecide":"0.6453","name":"weideman-RegexStaticAnalysis","patternVariant":"^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$","opinion":{"isSafe":0,"canAnalyze":1,"evilInput":[{"suffix":"B ","pumpPairs":[{"pump":".a","prefix":"Bearer a"},{"prefix":"a","pump":".a"}]}],"predictedComplexity":"polynomial"}},{"patternVariant":"^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$","opinion":{"isSafe":0,"canAnalyze":1,"evilInput":["COULD-NOT-PARSE"]},"hasOpinion":1,"secToDecide":"0.3439","name":"wuestholz-RegexCheck"},{"opinion":{"evilInput":[],"isSafe":true,"canAnalyze":true},"patternVariant":"^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$","name":"shen-ReScue","hasOpinion":1,"secToDecide":"19.0108"}],"timeLimit":"60","memoryLimit":"8192"}
Checking rathnayake-rxxr2 for timeout-triggering evil input
rathnayake-rxxr2: says not vulnerable
Checking weideman-RegexStaticAnalysis for timeout-triggering evil input
weideman-RegexStaticAnalysis: the regex may be vulnerable (isVariant 1)
weideman-RegexStaticAnalysis: Validating the evil input (query: {"language":"javascript","timeLimit":2,"nPumps":100000,"pattern":"^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$","evilInput":{"suffix":"B ","pumpPairs":[{"pump":".a","prefix":"Bearer a"},{"prefix":"a","pump":".a"}]}})
/home/jamie/Desktop/floss/vuln-regex-detector/src/validate/validate-vuln.pl /tmp/check-regex-12252.json 2>>/tmp/check-regex-12252-progress.log
weideman-RegexStaticAnalysis: evil input triggered a regex timeout
{"pattern":"^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$","validateReport":{"timedOut":1,"timeLimit":"2","language":"javascript","validPattern":1,"evilInput":{"suffix":"B ","pumpPairs":[{"pump":".a","prefix":"Bearer a"},{"pump":".a","prefix":"a"}]},"pattern":"^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$","nPumps":100000},"detectReport":{"pattern":"^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$","detectorOpinions":[{"patternVariant":"^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$","opinion":{"canAnalyze":0,"isSafe":"UNKNOWN"},"hasOpinion":1,"secToDecide":"0.0211","name":"rathnayake-rxxr2"},{"hasOpinion":1,"secToDecide":"0.6453","name":"weideman-RegexStaticAnalysis","patternVariant":"^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$","opinion":{"isSafe":0,"canAnalyze":1,"evilInput":[{"suffix":"B ","pumpPairs":[{"pump":".a","prefix":"Bearer a"},{"prefix":"a","pump":".a"}]}],"predictedComplexity":"polynomial"}},{"patternVariant":"^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$","opinion":{"isSafe":0,"canAnalyze":1,"evilInput":["COULD-NOT-PARSE"]},"hasOpinion":1,"secToDecide":"0.3439","name":"wuestholz-RegexCheck"},{"opinion":{"evilInput":[],"isSafe":true,"canAnalyze":true},"patternVariant":"^Bearer [.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?\\.[.a-zA-Z0-9\\-_]+?$","name":"shen-ReScue","hasOpinion":1,"secToDecide":"19.0108"}],"timeLimit":"60","memoryLimit":"8192"},"isVulnerable":1}
Looking at that output, we can see:
Checking rathnayake-rxxr2 for timeout-triggering evil input
rathnayake-rxxr2: says not vulnerable
Checking weideman-RegexStaticAnalysis for timeout-triggering evil input
weideman-RegexStaticAnalysis: the regex may be vulnerable (isVariant 1)
weideman-RegexStaticAnalysis: Validating the evil input ...
weideman-RegexStaticAnalysis: evil input triggered a regex timeout
which means that Weideman's tool found the regex vulnerable and proposed evil input. And using this input, Node.js took longer than your time threshold to perform the regex match.
I'm closing this issue since I think I've answered your questions. Please re-open if you have more to say.
@davisjam Thanks for the thorough explanation! đź‘Ť
Hi,
I tried running the detector using the npm module but I got back an INVALID message:
So I used Docker instead to build the image locally, then run it against a regex pattern for validating a JWT.
Here is the input file:
Here is part of the console output:
And here is the generated report:
I'm a bit confused. Is the regex vulnerable but the
wuestholz-RegexCheck
detector couldn't provide an example of an evil input? Is the regex safe?Please help! Thanks!
And thank you for creating this project!