circle-ir 4.9.12 → 4.9.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,6 +36,25 @@ export declare class BlockingMainThreadPass implements AnalysisPass<BlockingMain
36
36
  readonly name = "blocking-main-thread";
37
37
  readonly category: "performance";
38
38
  run(ctx: PassContext): BlockingMainThreadResult;
39
+ /**
40
+ * Synthetic `<verb>_handler` names that really do belong to an HTTP route.
41
+ *
42
+ * The extractor tags *any* function argument of *any* member-expression call
43
+ * this way, so `items.map(x => …)` becomes `map_handler` and
44
+ * `cache.get(k, () => …)` becomes `get_handler`. Accepting every
45
+ * `*_handler` would pull ordinary callbacks into a pass that is explicitly
46
+ * about the HTTP request path, so two conditions are required: the method is
47
+ * a router verb, and the callback's own parameters look like a request
48
+ * handler's — the same `HANDLER_PARAM_NAMES` test used for methods.
49
+ *
50
+ * Known limitation: `in_method` carries no receiver, so two callbacks that
51
+ * share a verb in one file are indistinguishable. A file containing both
52
+ * `app.get('/x', (req, res) => …)` and `cache.get(k, () => …)` will treat a
53
+ * blocking call in the second as in-handler. Both conditions still have to
54
+ * hold for the verb to register at all, which keeps that to files already
55
+ * mounting a real route of the same verb.
56
+ */
57
+ private collectInlineHandlerNames;
39
58
  private isRequestHandler;
40
59
  }
41
60
  //# sourceMappingURL=blocking-main-thread-pass.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"blocking-main-thread-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/blocking-main-thread-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AA0B9E,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,EAAE,KAAK,CAAC;QACxB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,aAAa,GAAG,QAAQ,CAAC;KAClC,CAAC,CAAC;CACJ;AAED,qBAAa,sBAAuB,YAAW,YAAY,CAAC,wBAAwB,CAAC;IACnF,QAAQ,CAAC,IAAI,0BAA0B;IACvC,QAAQ,CAAC,QAAQ,EAAG,aAAa,CAAU;IAE3C,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,wBAAwB;IA6D/C,OAAO,CAAC,gBAAgB;CAazB"}
1
+ {"version":3,"file":"blocking-main-thread-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/blocking-main-thread-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AA6C9E,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,EAAE,KAAK,CAAC;QACxB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,aAAa,GAAG,QAAQ,CAAC;KAClC,CAAC,CAAC;CACJ;AAED,qBAAa,sBAAuB,YAAW,YAAY,CAAC,wBAAwB,CAAC;IACnF,QAAQ,CAAC,IAAI,0BAA0B;IACvC,QAAQ,CAAC,QAAQ,EAAG,aAAa,CAAU;IAE3C,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,wBAAwB;IAiF/C;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,yBAAyB;IA4BjC,OAAO,CAAC,gBAAgB;CAazB"}
@@ -42,6 +42,22 @@ const CRYPTO_BLOCKING_METHODS = new Set([
42
42
  'generateKeyPairSync', 'generateKeySync', 'deriveKeySync',
43
43
  ]);
44
44
  const SYNC_SUFFIX_RE = /Sync$/;
45
+ /**
46
+ * Router methods that mount an HTTP request handler (Express / Koa / Hono /
47
+ * Fastify). Lowercase counterparts of HTTP_DECORATORS, plus `use` for
48
+ * middleware — middleware runs in the request path, so a blocking call there
49
+ * stalls the loop exactly as one in a route handler does.
50
+ */
51
+ const ROUTER_METHODS = new Set([
52
+ 'get', 'post', 'put', 'patch', 'delete', 'all', 'options', 'head', 'use',
53
+ ]);
54
+ /**
55
+ * Parameter list of a function passed as an argument, for the two shapes that
56
+ * appear as route callbacks: `(req, res) => …` / `async (req, res) => …` /
57
+ * `function (req, res) { … }` (group 1), and the single-parameter arrow
58
+ * `ctx => …` (group 2).
59
+ */
60
+ const FN_ARG_PARAMS_RE = /^(?:async\s+)?(?:function\s*[\w$]*\s*)?\(([^)]*)\)\s*(?:=>|\{)|^(?:async\s+)?([A-Za-z_$][\w$]*)\s*=>/;
45
61
  export class BlockingMainThreadPass {
46
62
  name = 'blocking-main-thread';
47
63
  category = 'performance';
@@ -64,8 +80,22 @@ export class BlockingMainThreadPass {
64
80
  }
65
81
  }
66
82
  }
67
- if (handlerRanges.length === 0)
83
+ // Inline route callbacks are invisible to the loop above: `app.get('/x',
84
+ // (req, res) => …)` produces no entry in `graph.ir.types`, so it has no
85
+ // method and no line range — which silently exempted the most common
86
+ // Express/Koa shape in the ecosystem (cognium-dev#315). A named
87
+ // `function handler(req, res)` was caught, because top-level functions do
88
+ // land in the synthetic `<module>` type; an inline arrow did not.
89
+ //
90
+ // No line range is needed. The calls extractor already names the enclosing
91
+ // function for this shape: an arrow or function-expression passed as an
92
+ // argument to a member-expression call is tagged `<property>_handler` by
93
+ // `findJSEnclosingFunction` (core/extractors/calls.ts), so a blocking call
94
+ // inside `app.get(…)` carries `in_method === 'get_handler'`.
95
+ const inlineHandlers = this.collectInlineHandlerNames(graph.ir.calls);
96
+ if (handlerRanges.length === 0 && inlineHandlers.size === 0) {
68
97
  return { blockingInHandlers: [] };
98
+ }
69
99
  const blockingInHandlers = [];
70
100
  for (const call of graph.ir.calls) {
71
101
  const name = call.method_name;
@@ -74,7 +104,11 @@ export class BlockingMainThreadPass {
74
104
  if (!isCrypto && !isSyncSuffix)
75
105
  continue;
76
106
  const line = call.location.line;
77
- const range = handlerRanges.find(r => line >= r.start && line <= r.end);
107
+ const enclosing = call.in_method ?? null;
108
+ const range = handlerRanges.find(r => line >= r.start && line <= r.end)
109
+ ?? (enclosing && inlineHandlers.has(enclosing)
110
+ ? { start: line, end: line, name: enclosing }
111
+ : undefined);
78
112
  if (!range)
79
113
  continue;
80
114
  const reason = isCrypto ? 'crypto' : 'sync-suffix';
@@ -97,6 +131,45 @@ export class BlockingMainThreadPass {
97
131
  }
98
132
  return { blockingInHandlers };
99
133
  }
134
+ /**
135
+ * Synthetic `<verb>_handler` names that really do belong to an HTTP route.
136
+ *
137
+ * The extractor tags *any* function argument of *any* member-expression call
138
+ * this way, so `items.map(x => …)` becomes `map_handler` and
139
+ * `cache.get(k, () => …)` becomes `get_handler`. Accepting every
140
+ * `*_handler` would pull ordinary callbacks into a pass that is explicitly
141
+ * about the HTTP request path, so two conditions are required: the method is
142
+ * a router verb, and the callback's own parameters look like a request
143
+ * handler's — the same `HANDLER_PARAM_NAMES` test used for methods.
144
+ *
145
+ * Known limitation: `in_method` carries no receiver, so two callbacks that
146
+ * share a verb in one file are indistinguishable. A file containing both
147
+ * `app.get('/x', (req, res) => …)` and `cache.get(k, () => …)` will treat a
148
+ * blocking call in the second as in-handler. Both conditions still have to
149
+ * hold for the verb to register at all, which keeps that to files already
150
+ * mounting a real route of the same verb.
151
+ */
152
+ collectInlineHandlerNames(calls) {
153
+ const names = new Set();
154
+ for (const call of calls) {
155
+ if (!ROUTER_METHODS.has(call.method_name))
156
+ continue;
157
+ for (const arg of call.arguments) {
158
+ const match = FN_ARG_PARAMS_RE.exec((arg.expression ?? '').trim());
159
+ if (!match)
160
+ continue;
161
+ const params = (match[1] ?? match[2] ?? '')
162
+ .split(',')
163
+ .map(p => p.trim().toLowerCase())
164
+ .filter(p => p.length > 0);
165
+ if (params.some(p => HANDLER_PARAM_NAMES.has(p))) {
166
+ names.add(`${call.method_name}_handler`);
167
+ break;
168
+ }
169
+ }
170
+ }
171
+ return names;
172
+ }
100
173
  isRequestHandler(method) {
101
174
  // NestJS / Fastify HTTP decorators
102
175
  if (method.annotations.some(a => HTTP_DECORATORS.has(a)))
@@ -1 +1 @@
1
- {"version":3,"file":"blocking-main-thread-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/blocking-main-thread-pass.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"blocking-main-thread-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/blocking-main-thread-pass.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"language-sources-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/language-sources-pass.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"language-sources-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/language-sources-pass.ts"],"names":[],"mappings":"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"}
@@ -333,6 +333,8 @@ export class LanguageSourcesPass {
333
333
  // Sprint 77a (#216 Pattern X): Jinja2 Environment(autoescape=...) +
334
334
  // .render(...) sanitizer.
335
335
  additionalSanitizers.push(...findPythonJinjaAutoescapeSanitizers(code));
336
+ // cognium-dev#293: user-defined CRLF-stripping helper credited at call sites.
337
+ additionalSanitizers.push(...findCrlfWrapperFunctionSanitizers(code, 'python'));
336
338
  // Sprint 71 (#190): pattern-based misconfig findings for subscript/context
337
339
  // assignment shapes (cors-wildcard-origin, xfo-csp-mismatch, tls-verify-
338
340
  // disabled) that the language-agnostic detectors miss in Python.
@@ -494,6 +496,12 @@ export class LanguageSourcesPass {
494
496
  ctx.addFinding(finding);
495
497
  }
496
498
  }
499
+ // -- C#: cognium-dev#286 C — Path.GetFullPath + !StartsWith(root) reject
500
+ // guard (the canonicalize-then-contain path-traversal defence). Java and
501
+ // JS/TS already credit their equivalents above; C# was the gap.
502
+ if (language === 'csharp') {
503
+ additionalSanitizers.push(...findCSharpFullPathStartsWithGuardSanitizers(code));
504
+ }
497
505
  // -- Java: Sprint 73 (#216 Pattern A) — Jackson readValue / Gson
498
506
  // fromJson recognized as ETE terminator (does not affect
499
507
  // configured `deserialization` sinks).
@@ -509,6 +517,8 @@ export class LanguageSourcesPass {
509
517
  // guard (the java.io.File OWASP-recommended containment defence).
510
518
  additionalSanitizers.push(...findJavaCanonicalPathStartsWithGuardSanitizers(code));
511
519
  additionalSanitizers.push(...findJavaInlineCrlfStripLogSanitizers(code));
520
+ // cognium-dev#293: the same strip, but living in a user-defined helper.
521
+ additionalSanitizers.push(...findCrlfWrapperFunctionSanitizers(code, 'java'));
512
522
  // Sprint 77a (#216 Pattern X): argv-form exec sanitizer.
513
523
  additionalSanitizers.push(...findJavaArgvFormExecSanitizers(code));
514
524
  // Sprint 78 (#190): Java misconfig pattern findings —
@@ -4614,8 +4624,10 @@ function findJsPathResolveStartsWithGuardSanitizers(code) {
4614
4624
  for (let l = c.line; l < Math.min(lines.length, c.line + 6); l++) {
4615
4625
  if (!guardRe.test(lines[l]))
4616
4626
  continue;
4617
- if (terminatorRe.test(lines[l]) ||
4618
- (l + 1 < lines.length && terminatorRe.test(lines[l + 1]))) {
4627
+ // Terminator on the guard line (single-line if) or the next one (block
4628
+ // form) but never the enclosing function's own terminator reached past
4629
+ // a guard block that already closed. See `guardRejects` (#333).
4630
+ if (guardRejects(lines, l, terminatorRe, 2)) {
4619
4631
  guardLine = l + 1;
4620
4632
  break;
4621
4633
  }
@@ -4800,10 +4812,11 @@ function findJavaPathNormalizeStartsWithGuardSanitizers(code) {
4800
4812
  for (let l = c.line; l < Math.min(lines.length, c.line + 6); l++) {
4801
4813
  if (!guardRe.test(lines[l]))
4802
4814
  continue;
4803
- // The terminator may be on the same line (single-line if) or on
4804
- // the next line (block-form if).
4805
- if (terminatorRe.test(lines[l]) ||
4806
- (l + 1 < lines.length && terminatorRe.test(lines[l + 1]))) {
4815
+ // The terminator may be on the same line (single-line if) or on the next
4816
+ // line (block-form if) — but never the enclosing function's own
4817
+ // terminator reached past a guard block that already closed. See
4818
+ // `guardRejects` (#333).
4819
+ if (guardRejects(lines, l, terminatorRe, 2)) {
4807
4820
  guardLine = l + 1;
4808
4821
  break;
4809
4822
  }
@@ -4881,18 +4894,7 @@ function findJavaCanonicalPathStartsWithGuardSanitizers(code) {
4881
4894
  const m = guardRe.exec(lines[i]);
4882
4895
  if (!m)
4883
4896
  continue;
4884
- let hasTerminator = terminatorRe.test(lines[i]);
4885
- if (!hasTerminator) {
4886
- for (let j = i + 1; j < Math.min(lines.length, i + 6); j++) {
4887
- if (terminatorRe.test(lines[j])) {
4888
- hasTerminator = true;
4889
- break;
4890
- }
4891
- if (lines[j].includes('}'))
4892
- break;
4893
- }
4894
- }
4895
- if (!hasTerminator)
4897
+ if (!guardRejects(lines, i, terminatorRe, 6))
4896
4898
  continue;
4897
4899
  const guarded = new Set([m[1]]);
4898
4900
  const mentions = (t) => {
@@ -4927,6 +4929,135 @@ function findJavaCanonicalPathStartsWithGuardSanitizers(code) {
4927
4929
  }
4928
4930
  return sanitizers;
4929
4931
  }
4932
+ /**
4933
+ * Does the `if (...)` guard on `lines[i]` actually **reject**?
4934
+ *
4935
+ * Path-containment guards (`!full.startsWith(root)`) only sanitise when the
4936
+ * failing branch leaves — returns or throws. A guard that merely logs lets
4937
+ * control fall through to the sink, so the path was never rejected and the
4938
+ * value is still attacker-controlled.
4939
+ *
4940
+ * cognium-dev#333: three guards got this wrong the same way. They scanned
4941
+ * forward from the guard line for a `return`/`throw` without noticing the
4942
+ * guard's own block had already closed, so
4943
+ *
4944
+ * if (!full.startsWith(root)) { log("odd"); }
4945
+ * return read(full); // <- this return was credited
4946
+ *
4947
+ * found the *enclosing method's* terminator and suppressed a genuine
4948
+ * path_traversal. Rust's equivalent (`findRustCanonicalizeGuardSanitizers`) was
4949
+ * the only one written correctly — it requires the guard line to open a block,
4950
+ * brace-matches to the close, and demands the terminator inside. This gives the
4951
+ * other three the same discipline cheaply.
4952
+ *
4953
+ * `window` bounds the forward scan and preserves each caller's original reach:
4954
+ * the canonical-path guard scanned six lines, the normalize and path.resolve
4955
+ * guards only looked at the next one.
4956
+ */
4957
+ function guardRejects(lines, i, terminatorRe, window) {
4958
+ // Single-line rejecting form: `if (!full.startsWith(root)) return null;`
4959
+ if (terminatorRe.test(lines[i]))
4960
+ return true;
4961
+ // Block opens and closes on the guard line with no terminator inside it, so
4962
+ // control falls through: `if (!full.startsWith(root)) { log("odd"); }`.
4963
+ const opens = (lines[i].match(/\{/g) ?? []).length;
4964
+ const closes = (lines[i].match(/\}/g) ?? []).length;
4965
+ if (opens > 0 && closes >= opens)
4966
+ return false;
4967
+ for (let j = i + 1; j < Math.min(lines.length, i + window); j++) {
4968
+ if (terminatorRe.test(lines[j]))
4969
+ return true;
4970
+ // Reached the end of the guard body without terminating.
4971
+ if (lines[j].includes('}'))
4972
+ return false;
4973
+ }
4974
+ return false;
4975
+ }
4976
+ /**
4977
+ * C# `Path.GetFullPath(...)` + `!x.StartsWith(root)` reject guard — the
4978
+ * canonicalize-then-contain path-traversal defence (cognium-dev#286 C).
4979
+ *
4980
+ * Counterpart of `findJavaCanonicalPathStartsWithGuardSanitizers` and
4981
+ * `findJsPathResolveStartsWithGuardSanitizers`; C# was the only one of the
4982
+ * three missing it, so the OWASP-canonical shape reported a false positive:
4983
+ *
4984
+ * var root = Path.GetFullPath("/srv/data") + Path.DirectorySeparatorChar;
4985
+ * var full = Path.GetFullPath(Path.Combine(root, input));
4986
+ * if (!full.StartsWith(root)) return;
4987
+ * File.ReadAllText(full); // was path_traversal
4988
+ *
4989
+ * `Path.GetFileName` is already credited, but it cannot express this case —
4990
+ * it flattens the path, so a legitimate subdirectory cannot be preserved.
4991
+ *
4992
+ * One requirement the Java version gets for free. There, canonicalisation and
4993
+ * the containment test are the same expression
4994
+ * (`!f.getCanonicalPath().startsWith(base)`), so matching the guard proves the
4995
+ * value is canonical. In C# they are separate statements, and the guard alone
4996
+ * is just `full.StartsWith(root)` — indistinguishable from an ordinary string
4997
+ * prefix test. Crediting on the guard alone would silence path_traversal for
4998
+ * any `if (!name.StartsWith("x")) return;`. So the guarded variable must also
4999
+ * be traceable to an assignment whose right-hand side calls
5000
+ * `Path.GetFullPath(`.
5001
+ *
5002
+ * Scope note: only the **reject** polarity (`if (!x.StartsWith(root))` plus a
5003
+ * `return`/`throw`) is credited, matching the Java precedent. The enclosing
5004
+ * form `if (x.StartsWith(root)) { … }` still reports, and a test pins that so
5005
+ * the gap stays visible rather than silently assumed.
5006
+ */
5007
+ function findCSharpFullPathStartsWithGuardSanitizers(code) {
5008
+ const sanitizers = [];
5009
+ const lines = code.split('\n');
5010
+ // Variables assigned from an expression that calls Path.GetFullPath(...).
5011
+ const assignRe = /^\s*(?:(?:var|string)\s+)?([A-Za-z_]\w*)\s*=(?!=)\s*(.*)$/;
5012
+ const fullPathRe = /\bPath\s*\.\s*GetFullPath\s*\(/;
5013
+ const canonicalVars = new Set();
5014
+ for (const line of lines) {
5015
+ const a = assignRe.exec(line);
5016
+ if (a && fullPathRe.test(a[2]))
5017
+ canonicalVars.add(a[1]);
5018
+ }
5019
+ if (canonicalVars.size === 0)
5020
+ return sanitizers;
5021
+ const guardRe = /\bif\s*\(\s*!\s*([A-Za-z_]\w*)\s*\.\s*StartsWith\s*\(/;
5022
+ const terminatorRe = /\b(throw|return)\b/;
5023
+ for (let i = 0; i < lines.length; i++) {
5024
+ const m = guardRe.exec(lines[i]);
5025
+ if (!m || !canonicalVars.has(m[1]))
5026
+ continue;
5027
+ if (!guardRejects(lines, i, terminatorRe, 6))
5028
+ continue;
5029
+ // Credit the guarded variable across the whole scan, as the Java version
5030
+ // does: a containment check proves the path is inside the root regardless
5031
+ // of where it was built, so a sink preceding the guard is safe too.
5032
+ // Derivations are still tracked in source order.
5033
+ const guarded = new Set([m[1]]);
5034
+ const mentions = (t) => {
5035
+ for (const n of guarded)
5036
+ if (new RegExp(`\\b${n}\\b`).test(t))
5037
+ return true;
5038
+ return false;
5039
+ };
5040
+ for (let l = 0; l < lines.length; l++) {
5041
+ const lt = lines[l];
5042
+ const a = assignRe.exec(lt);
5043
+ if (a) {
5044
+ if (mentions(a[2]))
5045
+ guarded.add(a[1]);
5046
+ else if (a[1] !== m[1])
5047
+ guarded.delete(a[1]);
5048
+ }
5049
+ if (mentions(lt)) {
5050
+ sanitizers.push({
5051
+ type: 'csharp_fullpath_startswith_guard',
5052
+ method: 'GetFullPath',
5053
+ line: l + 1,
5054
+ sanitizes: ['path_traversal', 'external_taint_escape'],
5055
+ });
5056
+ }
5057
+ }
5058
+ }
5059
+ return sanitizers;
5060
+ }
4930
5061
  function findJavaPathGetFileNameSanitizers(code) {
4931
5062
  const sanitizers = [];
4932
5063
  const lines = code.split('\n');
@@ -5002,6 +5133,76 @@ function findJavaPathGetFileNameSanitizers(code) {
5002
5133
  * Emits a `log_injection` + `external_taint_escape` sanitizer at
5003
5134
  * that line.
5004
5135
  */
5136
+ /**
5137
+ * Java / Python user-defined CRLF-stripping wrapper — credited at its call
5138
+ * sites (cognium-dev#293).
5139
+ *
5140
+ * `findJavaInlineCrlfStripLogSanitizers` only credits a strip applied *on the
5141
+ * log line itself*. When the strip lives in a small helper, the sanitizer was
5142
+ * detected inside the helper body and never reached the call site:
5143
+ *
5144
+ * private static String redact(String s) {
5145
+ * return s.replace("\r", "_").replace("\n", "_"); // sanitizer seen HERE
5146
+ * }
5147
+ * logger.info("user=" + redact(req.getParameter("user"))); // still log_injection
5148
+ *
5149
+ * JS/TS has had this for a while (`findJsWrapperFunctionSanitizers`); Java and
5150
+ * Python did not, which is two of the seven fixtures on #293.
5151
+ *
5152
+ * Scoped to CRLF / `log_injection` deliberately. The JS version also infers an
5153
+ * `xss` wrapper from an HTML char class, but #293 supplies no Java or Python
5154
+ * xss-wrapper fixture, and a sanitizer credit with no fixture behind it is how
5155
+ * a false negative gets shipped.
5156
+ *
5157
+ * Accepts three strip forms, matching what Java and Python actually write:
5158
+ * `.replaceAll("[\r\n]", …)`, `.replace('\n', …)`, `.replace("\r", …)`
5159
+ * and Python's `re.sub(r"[\r\n\t]", …)`.
5160
+ * The double-quoted `replace("\r", …)` form is notably absent from the inline
5161
+ * detector above, which is part of why the fixture on #293 reported.
5162
+ *
5163
+ * A helper qualifies only if it is a *value-returning* declaration whose body
5164
+ * strips CRLF. In Java that means an explicit `String`/`CharSequence` return
5165
+ * type, which keeps `void` log-and-forget methods out.
5166
+ */
5167
+ function findCrlfWrapperFunctionSanitizers(code, language) {
5168
+ const sanitizers = [];
5169
+ const lines = code.split('\n');
5170
+ const declRe = language === 'java'
5171
+ ? /^\s*(?:public|private|protected)?\s*(?:static\s+)?(?:final\s+)?(?:String|CharSequence)\s+([A-Za-z_]\w*)\s*\(/
5172
+ : /^\s*def\s+([A-Za-z_]\w*)\s*\(/;
5173
+ // `\\[rnt]` matches the two-character escape as it appears in source text.
5174
+ const stripRe = language === 'java'
5175
+ ? /\.\s*replace(?:All)?\s*\(\s*(?:"[^"]*\\[rnt]|'\\[rnt]')/
5176
+ : /(?:re\s*\.\s*sub\s*\(\s*r?["'][^"']*\\[rnt]|\.\s*replace\s*\(\s*["']\\[rnt])/;
5177
+ const bodyWindow = 10;
5178
+ const wrappers = new Set();
5179
+ for (let i = 0; i < lines.length; i++) {
5180
+ const m = declRe.exec(lines[i]);
5181
+ if (!m)
5182
+ continue;
5183
+ const body = lines.slice(i, Math.min(lines.length, i + bodyWindow)).join('\n');
5184
+ if (stripRe.test(body))
5185
+ wrappers.add(m[1]);
5186
+ }
5187
+ if (wrappers.size === 0)
5188
+ return sanitizers;
5189
+ for (let i = 0; i < lines.length; i++) {
5190
+ for (const name of wrappers) {
5191
+ // Never credit the declaration line itself.
5192
+ if (declRe.test(lines[i]) && new RegExp(`\\b${name}\\s*\\(`).test(lines[i]))
5193
+ continue;
5194
+ if (!new RegExp(`\\b${name}\\s*\\(`).test(lines[i]))
5195
+ continue;
5196
+ sanitizers.push({
5197
+ type: language === 'java' ? 'java_wrapper_crlf_strip' : 'python_wrapper_crlf_strip',
5198
+ method: name,
5199
+ line: i + 1,
5200
+ sanitizes: ['log_injection', 'external_taint_escape'],
5201
+ });
5202
+ }
5203
+ }
5204
+ return sanitizers;
5205
+ }
5005
5206
  function findJavaInlineCrlfStripLogSanitizers(code) {
5006
5207
  const sanitizers = [];
5007
5208
  const lines = code.split('\n');