|
23 | 23 | import cpp |
24 | 24 | private import semmle.code.cpp.regex.internal.StdRegex |
25 | 25 |
|
26 | | -// --------------------------------------------------------------------------- |
27 | | -// Fast-path filter: only consider literals that *look* regex-y |
28 | | -// --------------------------------------------------------------------------- |
29 | | -/** |
30 | | - * Holds if `s` is a plausible ReDoS-candidate string literal value: it |
31 | | - * contains at least one unbounded-repetition quantifier (`+`, `*`, or |
32 | | - * `{n,}`). |
33 | | - * |
34 | | - * This mirrors the source restriction of the dataflow configuration in |
35 | | - * `RegexFlowConfigs` (whose sources are the `ExploitableStringLiteral`s), |
36 | | - * so that the flag readers below consider exactly the same set of regexes |
37 | | - * as the taint-tracking configuration. Inlined here as a syntactic check |
38 | | - * to keep this module flow-free. |
39 | | - */ |
40 | | -private predicate isExploitableStringLiteralValue(StringLiteral s) { |
41 | | - exists(string v | v = s.getValue() | |
42 | | - v.regexpMatch(".*[+*].*") or |
43 | | - v.regexpMatch(".*\\{[0-9]+,[0-9]*\\}.*") |
44 | | - ) |
45 | | -} |
46 | | - |
47 | 26 | // --------------------------------------------------------------------------- |
48 | 27 | // Construction-site flag readers (std::regex_constants enum plumbing) |
49 | 28 | // --------------------------------------------------------------------------- |
@@ -108,32 +87,23 @@ private predicate isPatternLiteralOf(StringLiteral regex, Expr patternArg) { |
108 | 87 | * |
109 | 88 | * This association is purely syntactic (no dataflow): the pattern literal |
110 | 89 | * must appear inside the constructor/assign call's first argument. |
111 | | - * |
112 | | - * Restricted to string literals that look like plausible ReDoS candidates |
113 | | - * (see `isExploitableStringLiteralValue`) to preserve the exact set of |
114 | | - * regexes considered by the flag readers when they were routed through |
115 | | - * the taint-tracking configuration (whose sources are the same |
116 | | - * `ExploitableStringLiteral` set). |
117 | 90 | */ |
118 | 91 | private Expr getConstructionFlagArg(StringLiteral regex) { |
119 | | - isExploitableStringLiteralValue(regex) and |
120 | | - ( |
121 | | - // basic_regex(pattern, flags) constructor - both named-variable and |
122 | | - // temporary constructions are covered because the search for `regex` |
123 | | - // is done syntactically inside the constructor's first argument. |
124 | | - exists(ConstructorCall cc | |
125 | | - cc.getTarget().getDeclaringType() instanceof StdBasicRegex and |
126 | | - isPatternLiteralOf(regex, cc.getArgument(0)) and |
127 | | - result = cc.getArgument(1) |
128 | | - ) |
129 | | - or |
130 | | - // basic_regex::assign(pattern, flags). |
131 | | - exists(FunctionCall fc | |
132 | | - fc.getTarget().(MemberFunction).getDeclaringType() instanceof StdBasicRegex and |
133 | | - fc.getTarget().hasName("assign") and |
134 | | - isPatternLiteralOf(regex, fc.getArgument(0)) and |
135 | | - result = fc.getArgument(1) |
136 | | - ) |
| 92 | + // basic_regex(pattern, flags) constructor - both named-variable and |
| 93 | + // temporary constructions are covered because the search for `regex` |
| 94 | + // is done syntactically inside the constructor's first argument. |
| 95 | + exists(ConstructorCall cc | |
| 96 | + cc.getTarget().getDeclaringType() instanceof StdBasicRegex and |
| 97 | + isPatternLiteralOf(regex, cc.getArgument(0)) and |
| 98 | + result = cc.getArgument(1) |
| 99 | + ) |
| 100 | + or |
| 101 | + // basic_regex::assign(pattern, flags). |
| 102 | + exists(FunctionCall fc | |
| 103 | + fc.getTarget().(MemberFunction).getDeclaringType() instanceof StdBasicRegex and |
| 104 | + fc.getTarget().hasName("assign") and |
| 105 | + isPatternLiteralOf(regex, fc.getArgument(0)) and |
| 106 | + result = fc.getArgument(1) |
137 | 107 | ) |
138 | 108 | } |
139 | 109 |
|
|
0 commit comments