circle-ir 4.14.2 → 4.16.0
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.
- package/configs/sinks/golang.json +4 -4
- package/dist/analysis/config-loader.d.ts.map +1 -1
- package/dist/analysis/config-loader.js +11 -7
- package/dist/analysis/config-loader.js.map +1 -1
- package/dist/analysis/const-table-lookup.d.ts +29 -0
- package/dist/analysis/const-table-lookup.d.ts.map +1 -0
- package/dist/analysis/const-table-lookup.js +145 -0
- package/dist/analysis/const-table-lookup.js.map +1 -0
- package/dist/analysis/constant-caller-gate.d.ts +39 -0
- package/dist/analysis/constant-caller-gate.d.ts.map +1 -0
- package/dist/analysis/constant-caller-gate.js +298 -0
- package/dist/analysis/constant-caller-gate.js.map +1 -0
- package/dist/analysis/constant-propagation/evaluator.d.ts.map +1 -1
- package/dist/analysis/constant-propagation/evaluator.js +3 -1
- package/dist/analysis/constant-propagation/evaluator.js.map +1 -1
- package/dist/analysis/constant-propagation/patterns.d.ts +19 -0
- package/dist/analysis/constant-propagation/patterns.d.ts.map +1 -1
- package/dist/analysis/constant-propagation/patterns.js +33 -0
- package/dist/analysis/constant-propagation/patterns.js.map +1 -1
- package/dist/analysis/constant-propagation/propagator.d.ts +59 -0
- package/dist/analysis/constant-propagation/propagator.d.ts.map +1 -1
- package/dist/analysis/constant-propagation/propagator.js +396 -49
- package/dist/analysis/constant-propagation/propagator.js.map +1 -1
- package/dist/analysis/constant-propagation/types.d.ts +9 -0
- package/dist/analysis/constant-propagation/types.d.ts.map +1 -1
- package/dist/analysis/findings.d.ts.map +1 -1
- package/dist/analysis/findings.js +149 -4
- package/dist/analysis/findings.js.map +1 -1
- package/dist/analysis/go-strings-replacer.d.ts +21 -0
- package/dist/analysis/go-strings-replacer.d.ts.map +1 -0
- package/dist/analysis/go-strings-replacer.js +145 -0
- package/dist/analysis/go-strings-replacer.js.map +1 -0
- package/dist/analysis/interprocedural.d.ts.map +1 -1
- package/dist/analysis/interprocedural.js +148 -0
- package/dist/analysis/interprocedural.js.map +1 -1
- package/dist/analysis/java-array-element-keys.d.ts +14 -0
- package/dist/analysis/java-array-element-keys.d.ts.map +1 -0
- package/dist/analysis/java-array-element-keys.js +36 -0
- package/dist/analysis/java-array-element-keys.js.map +1 -0
- package/dist/analysis/java-canonical-prefix.d.ts +42 -0
- package/dist/analysis/java-canonical-prefix.d.ts.map +1 -0
- package/dist/analysis/java-canonical-prefix.js +145 -0
- package/dist/analysis/java-canonical-prefix.js.map +1 -0
- package/dist/analysis/java-crlf-strip.d.ts +30 -0
- package/dist/analysis/java-crlf-strip.d.ts.map +1 -0
- package/dist/analysis/java-crlf-strip.js +195 -0
- package/dist/analysis/java-crlf-strip.js.map +1 -0
- package/dist/analysis/js-crlf-strip.d.ts +26 -0
- package/dist/analysis/js-crlf-strip.d.ts.map +1 -0
- package/dist/analysis/js-crlf-strip.js +244 -0
- package/dist/analysis/js-crlf-strip.js.map +1 -0
- package/dist/analysis/passes/cleartext-credential-transport-pass.d.ts +2 -0
- package/dist/analysis/passes/cleartext-credential-transport-pass.d.ts.map +1 -1
- package/dist/analysis/passes/cleartext-credential-transport-pass.js +64 -12
- package/dist/analysis/passes/cleartext-credential-transport-pass.js.map +1 -1
- package/dist/analysis/passes/cross-file-pass.d.ts.map +1 -1
- package/dist/analysis/passes/cross-file-pass.js +43 -0
- package/dist/analysis/passes/cross-file-pass.js.map +1 -1
- package/dist/analysis/passes/csharp-sanitizer-credit.d.ts +12 -0
- package/dist/analysis/passes/csharp-sanitizer-credit.d.ts.map +1 -1
- package/dist/analysis/passes/csharp-sanitizer-credit.js +127 -12
- package/dist/analysis/passes/csharp-sanitizer-credit.js.map +1 -1
- package/dist/analysis/passes/interprocedural-pass.d.ts +28 -0
- package/dist/analysis/passes/interprocedural-pass.d.ts.map +1 -1
- package/dist/analysis/passes/interprocedural-pass.js +20 -1
- package/dist/analysis/passes/interprocedural-pass.js.map +1 -1
- package/dist/analysis/passes/language-sources-pass.d.ts +76 -2
- package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
- package/dist/analysis/passes/language-sources-pass.js +2045 -156
- package/dist/analysis/passes/language-sources-pass.js.map +1 -1
- package/dist/analysis/passes/param-source-flow-gate-pass.d.ts +8 -0
- package/dist/analysis/passes/param-source-flow-gate-pass.d.ts.map +1 -1
- package/dist/analysis/passes/param-source-flow-gate-pass.js +214 -6
- package/dist/analysis/passes/param-source-flow-gate-pass.js.map +1 -1
- package/dist/analysis/passes/plaintext-password-storage-pass.d.ts +6 -0
- package/dist/analysis/passes/plaintext-password-storage-pass.d.ts.map +1 -1
- package/dist/analysis/passes/plaintext-password-storage-pass.js +160 -0
- package/dist/analysis/passes/plaintext-password-storage-pass.js.map +1 -1
- package/dist/analysis/passes/scan-secrets-pass.d.ts +1 -1
- package/dist/analysis/passes/scan-secrets-pass.d.ts.map +1 -1
- package/dist/analysis/passes/scan-secrets-pass.js +7 -1
- package/dist/analysis/passes/scan-secrets-pass.js.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.d.ts +1 -1
- package/dist/analysis/passes/sink-filter-pass.d.ts.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.js +509 -27
- package/dist/analysis/passes/sink-filter-pass.js.map +1 -1
- package/dist/analysis/passes/taint-matcher-pass.d.ts.map +1 -1
- package/dist/analysis/passes/taint-matcher-pass.js +2 -2
- package/dist/analysis/passes/taint-matcher-pass.js.map +1 -1
- package/dist/analysis/passes/taint-propagation-pass.d.ts.map +1 -1
- package/dist/analysis/passes/taint-propagation-pass.js +1606 -60
- package/dist/analysis/passes/taint-propagation-pass.js.map +1 -1
- package/dist/analysis/passes/weak-hash-pass.d.ts +6 -0
- package/dist/analysis/passes/weak-hash-pass.d.ts.map +1 -1
- package/dist/analysis/passes/weak-hash-pass.js +191 -4
- package/dist/analysis/passes/weak-hash-pass.js.map +1 -1
- package/dist/analysis/passes/weak-random-pass.d.ts +5 -0
- package/dist/analysis/passes/weak-random-pass.d.ts.map +1 -1
- package/dist/analysis/passes/weak-random-pass.js +30 -0
- package/dist/analysis/passes/weak-random-pass.js.map +1 -1
- package/dist/analysis/project-callee-escape-gate.d.ts +40 -0
- package/dist/analysis/project-callee-escape-gate.d.ts.map +1 -0
- package/dist/analysis/project-callee-escape-gate.js +243 -0
- package/dist/analysis/project-callee-escape-gate.js.map +1 -0
- package/dist/analysis/rust-literal-guard-rebind.d.ts +34 -0
- package/dist/analysis/rust-literal-guard-rebind.d.ts.map +1 -0
- package/dist/analysis/rust-literal-guard-rebind.js +197 -0
- package/dist/analysis/rust-literal-guard-rebind.js.map +1 -0
- package/dist/analysis/rust-literal-guard.d.ts +33 -0
- package/dist/analysis/rust-literal-guard.d.ts.map +1 -0
- package/dist/analysis/rust-literal-guard.js +422 -0
- package/dist/analysis/rust-literal-guard.js.map +1 -0
- package/dist/analysis/scalar-derivation.d.ts +33 -0
- package/dist/analysis/scalar-derivation.d.ts.map +1 -0
- package/dist/analysis/scalar-derivation.js +368 -0
- package/dist/analysis/scalar-derivation.js.map +1 -0
- package/dist/analysis/taint-matcher.d.ts +2 -2
- package/dist/analysis/taint-matcher.d.ts.map +1 -1
- package/dist/analysis/taint-matcher.js +695 -34
- package/dist/analysis/taint-matcher.js.map +1 -1
- package/dist/analysis/taint-propagation.d.ts +26 -1
- package/dist/analysis/taint-propagation.d.ts.map +1 -1
- package/dist/analysis/taint-propagation.js +375 -24
- package/dist/analysis/taint-propagation.js.map +1 -1
- package/dist/analyzer.d.ts +16 -2
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +19 -2
- package/dist/analyzer.js.map +1 -1
- package/dist/browser/circle-ir.js +25539 -19200
- package/dist/core/circle-ir-core.cjs +3945 -2126
- package/dist/core/circle-ir-core.js +3945 -2126
- package/dist/core/extractors/calls.d.ts +12 -1
- package/dist/core/extractors/calls.d.ts.map +1 -1
- package/dist/core/extractors/calls.js +332 -22
- package/dist/core/extractors/calls.js.map +1 -1
- package/dist/core/extractors/dfg.js +336 -10
- package/dist/core/extractors/dfg.js.map +1 -1
- package/dist/core/extractors/types.d.ts +5 -1
- package/dist/core/extractors/types.d.ts.map +1 -1
- package/dist/core/extractors/types.js +62 -0
- package/dist/core/extractors/types.js.map +1 -1
- package/dist/graph/analysis-pass.d.ts +6 -1
- package/dist/graph/analysis-pass.d.ts.map +1 -1
- package/dist/graph/analysis-pass.js +2 -1
- package/dist/graph/analysis-pass.js.map +1 -1
- package/dist/graph/code-graph.d.ts +9 -0
- package/dist/graph/code-graph.d.ts.map +1 -1
- package/dist/graph/code-graph.js +11 -0
- package/dist/graph/code-graph.js.map +1 -1
- package/dist/navigation/navigation-index.d.ts +134 -14
- package/dist/navigation/navigation-index.d.ts.map +1 -1
- package/dist/navigation/navigation-index.js +1158 -104
- package/dist/navigation/navigation-index.js.map +1 -1
- package/dist/navigation/types.d.ts +59 -2
- package/dist/navigation/types.d.ts.map +1 -1
- package/dist/resolution/cross-file.d.ts +16 -0
- package/dist/resolution/cross-file.d.ts.map +1 -1
- package/dist/resolution/cross-file.js +110 -42
- package/dist/resolution/cross-file.js.map +1 -1
- package/dist/resolution/type-hierarchy.d.ts +3 -0
- package/dist/resolution/type-hierarchy.d.ts.map +1 -1
- package/dist/resolution/type-hierarchy.js +45 -1
- package/dist/resolution/type-hierarchy.js.map +1 -1
- package/dist/types/index.d.ts +33 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/wasm/web-tree-sitter.wasm +0 -0
- package/package.json +3 -3
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
import { firstRebind } from './rust-literal-guard-rebind.js';
|
|
2
|
+
const CREDITED_TYPES = [
|
|
3
|
+
'command_injection', 'path_traversal', 'sql_injection', 'ssrf', 'open_redirect',
|
|
4
|
+
'xss', 'code_injection', 'ldap_injection', 'xpath_injection', 'log_injection',
|
|
5
|
+
'trust_boundary', 'external_taint_escape',
|
|
6
|
+
];
|
|
7
|
+
/** `code` with comments blanked and string / char literal bodies replaced by spaces (same length). */
|
|
8
|
+
function maskRust(code) {
|
|
9
|
+
const out = code.split('');
|
|
10
|
+
const n = code.length;
|
|
11
|
+
const blank = (from, to) => {
|
|
12
|
+
for (let k = from; k < to; k++)
|
|
13
|
+
if (out[k] !== '\n')
|
|
14
|
+
out[k] = ' ';
|
|
15
|
+
};
|
|
16
|
+
let i = 0;
|
|
17
|
+
while (i < n) {
|
|
18
|
+
const c = code[i];
|
|
19
|
+
if (c === '/' && code[i + 1] === '/') {
|
|
20
|
+
let j = i;
|
|
21
|
+
while (j < n && code[j] !== '\n')
|
|
22
|
+
j++;
|
|
23
|
+
blank(i, j);
|
|
24
|
+
i = j;
|
|
25
|
+
}
|
|
26
|
+
else if (c === '/' && code[i + 1] === '*') {
|
|
27
|
+
let j = i + 2;
|
|
28
|
+
let depth = 1;
|
|
29
|
+
while (j < n && depth > 0) {
|
|
30
|
+
if (code[j] === '/' && code[j + 1] === '*') {
|
|
31
|
+
depth++;
|
|
32
|
+
j += 2;
|
|
33
|
+
}
|
|
34
|
+
else if (code[j] === '*' && code[j + 1] === '/') {
|
|
35
|
+
depth--;
|
|
36
|
+
j += 2;
|
|
37
|
+
}
|
|
38
|
+
else
|
|
39
|
+
j++;
|
|
40
|
+
}
|
|
41
|
+
blank(i, j);
|
|
42
|
+
i = j;
|
|
43
|
+
}
|
|
44
|
+
else if (c === 'r' && /^r#*"/.test(code.slice(i, i + 12)) && !/[\w]/.test(code[i - 1] ?? ' ')) {
|
|
45
|
+
const hashes = /^r(#*)"/.exec(code.slice(i, i + 12))[1].length;
|
|
46
|
+
const close = '"' + '#'.repeat(hashes);
|
|
47
|
+
const end = code.indexOf(close, i + 2 + hashes);
|
|
48
|
+
const j = end === -1 ? n : end + close.length;
|
|
49
|
+
blank(i + 2 + hashes, Math.max(i + 2 + hashes, j - close.length));
|
|
50
|
+
i = j;
|
|
51
|
+
}
|
|
52
|
+
else if (c === '"') {
|
|
53
|
+
let j = i + 1;
|
|
54
|
+
while (j < n && code[j] !== '"')
|
|
55
|
+
j += code[j] === '\\' ? 2 : 1;
|
|
56
|
+
blank(i + 1, j);
|
|
57
|
+
i = j + 1;
|
|
58
|
+
}
|
|
59
|
+
else if (c === "'") {
|
|
60
|
+
// A char literal ('x', '\n', '\u{..}'), not a lifetime ('a).
|
|
61
|
+
const m = /^'(?:\\(?:u\{[0-9a-fA-F]+\}|x[0-9a-fA-F]{2}|.)|[^\\'])'/.exec(code.slice(i, i + 14));
|
|
62
|
+
if (m) {
|
|
63
|
+
blank(i + 1, i + m[0].length - 1);
|
|
64
|
+
i += m[0].length;
|
|
65
|
+
}
|
|
66
|
+
else
|
|
67
|
+
i++;
|
|
68
|
+
}
|
|
69
|
+
else
|
|
70
|
+
i++;
|
|
71
|
+
}
|
|
72
|
+
return out.join('');
|
|
73
|
+
}
|
|
74
|
+
/** Index of the `}` matching the `{` at `open` in `masked`, or -1. */
|
|
75
|
+
function matchBrace(masked, open) {
|
|
76
|
+
let depth = 0;
|
|
77
|
+
for (let i = open; i < masked.length; i++) {
|
|
78
|
+
if (masked[i] === '{')
|
|
79
|
+
depth++;
|
|
80
|
+
else if (masked[i] === '}' && --depth === 0)
|
|
81
|
+
return i;
|
|
82
|
+
}
|
|
83
|
+
return -1;
|
|
84
|
+
}
|
|
85
|
+
const STR = String.raw `"(?:[^"\\]|\\.)*"`;
|
|
86
|
+
const VAR = String.raw `([A-Za-z_]\w*)(?:\s*\.\s*as_str\s*\(\s*\))?`;
|
|
87
|
+
/** The guarded variable when `cond` is a literal allow-list rejection condition, else null. */
|
|
88
|
+
function guardedVariable(cond) {
|
|
89
|
+
const c = cond.trim();
|
|
90
|
+
let m;
|
|
91
|
+
// `!matches!(x, "a" | "b")`
|
|
92
|
+
if ((m = new RegExp(String.raw `^!\s*matches!\s*\(\s*${VAR}\s*,\s*((?:\|\s*)?${STR}(?:\s*\|\s*${STR})*)\s*,?\s*\)$`).exec(c))) {
|
|
93
|
+
return m[1];
|
|
94
|
+
}
|
|
95
|
+
// `!["a", "b"].contains(&x)`
|
|
96
|
+
if ((m = new RegExp(String.raw `^!\s*\[\s*${STR}(?:\s*,\s*${STR})*\s*,?\s*\]\s*\.\s*contains\s*\(\s*&\s*${VAR}\s*\)$`).exec(c))) {
|
|
97
|
+
return m[1];
|
|
98
|
+
}
|
|
99
|
+
// `!(x == "a" || x == "b")`
|
|
100
|
+
if ((m = /^!\s*\(([\s\S]*)\)$/.exec(c))) {
|
|
101
|
+
return chain(m[1], '||', '==');
|
|
102
|
+
}
|
|
103
|
+
// `x != "a" && x != "b"`
|
|
104
|
+
return chain(c, '&&', '!=');
|
|
105
|
+
}
|
|
106
|
+
/** Terms joined by `joiner`, each `V op "lit"` or `"lit" op V` with one shared V. */
|
|
107
|
+
function chain(text, joiner, op) {
|
|
108
|
+
const other = joiner === '||' ? '&&' : '||';
|
|
109
|
+
if (text.includes(other) || /[()]/.test(text.replace(/\.\s*as_str\s*\(\s*\)/g, '').replace(new RegExp(STR, 'g'), '""'))) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
let name = null;
|
|
113
|
+
const parts = text.split(joiner);
|
|
114
|
+
for (const part of parts) {
|
|
115
|
+
const t = part.trim();
|
|
116
|
+
const m = new RegExp(String.raw `^(?:${VAR}\s*${op}\s*${STR}|${STR}\s*${op}\s*${VAR})$`).exec(t);
|
|
117
|
+
if (!m)
|
|
118
|
+
return null;
|
|
119
|
+
const v = m[1] ?? m[2];
|
|
120
|
+
if (name !== null && v !== name)
|
|
121
|
+
return null;
|
|
122
|
+
name = v;
|
|
123
|
+
}
|
|
124
|
+
return name;
|
|
125
|
+
}
|
|
126
|
+
const KEYWORDS = new Set([
|
|
127
|
+
'let', 'mut', 'ref', 'as', 'if', 'else', 'return', 'true', 'false', 'self', 'move', 'in', 'for',
|
|
128
|
+
'while', 'loop', 'match', 'fn', 'pub', 'use', 'mod', 'const', 'static', 'unsafe', 'where', 'dyn',
|
|
129
|
+
'impl', 'break', 'continue', 'crate', 'super', 'async', 'await', 'box', 'type', 'struct', 'enum',
|
|
130
|
+
'str', 'u8', 'u16', 'u32', 'u64', 'usize', 'i8', 'i16', 'i32', 'i64', 'isize', 'bool', 'char', 'f32', 'f64',
|
|
131
|
+
]);
|
|
132
|
+
/**
|
|
133
|
+
* True when the (masked) `line` reads a value other than `name`: another
|
|
134
|
+
* local, a lower-case free or module-qualified call (`std::env::args()`), or
|
|
135
|
+
* an inline format argument (`{other}`). Method names, associated functions
|
|
136
|
+
* of a type (`Command::new`), macros, type names and closure parameters are
|
|
137
|
+
* not values.
|
|
138
|
+
*/
|
|
139
|
+
function readsOtherValue(original, masked, name) {
|
|
140
|
+
for (const m of original.matchAll(new RegExp(STR, 'g'))) {
|
|
141
|
+
for (const f of m[0].matchAll(/(?<!\{)\{([A-Za-z_]\w*)(?:[:}])/g))
|
|
142
|
+
if (f[1] !== name)
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
const closureParams = new Set();
|
|
146
|
+
for (const m of masked.matchAll(/\|\s*([\w\s,&:()]*?)\s*\|/g)) {
|
|
147
|
+
for (const p of m[1].matchAll(/[A-Za-z_]\w*/g))
|
|
148
|
+
closureParams.add(p[0]);
|
|
149
|
+
}
|
|
150
|
+
const re = /[A-Za-z_]\w*/g;
|
|
151
|
+
let m;
|
|
152
|
+
while ((m = re.exec(masked)) !== null) {
|
|
153
|
+
const id = m[0];
|
|
154
|
+
const before = masked.slice(0, m.index);
|
|
155
|
+
const after = masked.slice(m.index + id.length);
|
|
156
|
+
if (id === name || KEYWORDS.has(id) || closureParams.has(id))
|
|
157
|
+
continue;
|
|
158
|
+
if (/\.\s*$/.test(before))
|
|
159
|
+
continue; // method or field
|
|
160
|
+
if (/^\s*!/.test(after) && !/^\s*!=/.test(after))
|
|
161
|
+
continue; // macro
|
|
162
|
+
if (/[A-Z]/.test(id[0]))
|
|
163
|
+
continue; // type, variant, constant
|
|
164
|
+
if (/(?:\blet\s+(?:mut\s+)?)$/.test(before))
|
|
165
|
+
continue; // the binding being introduced
|
|
166
|
+
if (/::\s*$/.test(before))
|
|
167
|
+
continue; // path tail (`io::stdin` handled by its head)
|
|
168
|
+
return true; // other local, free call, module path
|
|
169
|
+
}
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* `&mut` parameter only: the bare name passed as a call argument can be
|
|
174
|
+
* mutated by the callee (checked per line).
|
|
175
|
+
*/
|
|
176
|
+
function passesMutParam(line, n) {
|
|
177
|
+
if (!new RegExp(String.raw `(?<![\w.])(?:[A-Za-z_]\w*(?:\s*::\s*[A-Za-z_]\w*)*)\s*\((?:[^)]*,\s*)?${n}\b`).test(line))
|
|
178
|
+
return false;
|
|
179
|
+
// Exclude method calls on name itself (`name.foo(`), handled by firstRebind.
|
|
180
|
+
return !new RegExp(String.raw `\b${n}\s*\.\s*\w+\s*\(`).test(line) || new RegExp(String.raw `(?<![\w.])\w+\s*\(\s*${n}\b`).test(line);
|
|
181
|
+
}
|
|
182
|
+
export function findRustLiteralEqualityGuardSanitizers(code) {
|
|
183
|
+
const masked = maskRust(code);
|
|
184
|
+
const origLines = code.split('\n');
|
|
185
|
+
const maskedLines = masked.split('\n');
|
|
186
|
+
const lineStarts = [];
|
|
187
|
+
for (let i = 0, off = 0; i < origLines.length; i++) {
|
|
188
|
+
lineStarts.push(off);
|
|
189
|
+
off += origLines[i].length + 1;
|
|
190
|
+
}
|
|
191
|
+
const lineOf = (idx) => {
|
|
192
|
+
let lo = 0, hi = lineStarts.length - 1;
|
|
193
|
+
while (lo < hi) {
|
|
194
|
+
const mid = (lo + hi + 1) >> 1;
|
|
195
|
+
if (lineStarts[mid] <= idx)
|
|
196
|
+
lo = mid;
|
|
197
|
+
else
|
|
198
|
+
hi = mid - 1;
|
|
199
|
+
}
|
|
200
|
+
return lo; // 0-based
|
|
201
|
+
};
|
|
202
|
+
const out = [];
|
|
203
|
+
for (const ifm of masked.matchAll(/\bif\b/g)) {
|
|
204
|
+
const at = ifm.index;
|
|
205
|
+
if (/\belse\s*$/.test(masked.slice(Math.max(0, at - 12), at)))
|
|
206
|
+
continue;
|
|
207
|
+
if (/\blet\b/.test(masked.slice(at + 2, at + 8)))
|
|
208
|
+
continue; // `if let`
|
|
209
|
+
// Condition: up to the `{` that opens the block, at bracket depth 0.
|
|
210
|
+
let depth = 0;
|
|
211
|
+
let open = -1;
|
|
212
|
+
for (let i = at + 2; i < masked.length; i++) {
|
|
213
|
+
const ch = masked[i];
|
|
214
|
+
if (ch === '(' || ch === '[')
|
|
215
|
+
depth++;
|
|
216
|
+
else if (ch === ')' || ch === ']')
|
|
217
|
+
depth--;
|
|
218
|
+
else if (ch === '{' && depth === 0) {
|
|
219
|
+
open = i;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
else if (ch === ';' || ch === '}')
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
if (open < 0)
|
|
226
|
+
continue;
|
|
227
|
+
const name = guardedVariable(code.slice(at + 2, open));
|
|
228
|
+
if (name === null)
|
|
229
|
+
continue;
|
|
230
|
+
const close = matchBrace(masked, open);
|
|
231
|
+
if (close < 0)
|
|
232
|
+
continue;
|
|
233
|
+
if (/^\s*else\b/.test(masked.slice(close + 1, close + 12)))
|
|
234
|
+
continue;
|
|
235
|
+
// The block must reject at its own top level (not inside an inner branch).
|
|
236
|
+
// Strip nested braces and braceless closure bodies (`|…| expr`) so a
|
|
237
|
+
// `return` inside a closure does not count as the guard rejecting.
|
|
238
|
+
const body = masked.slice(open + 1, close).split('');
|
|
239
|
+
for (let i = 0, d = 0; i < body.length; i++) {
|
|
240
|
+
if (body[i] === '{') {
|
|
241
|
+
d++;
|
|
242
|
+
body[i] = ' ';
|
|
243
|
+
}
|
|
244
|
+
else if (body[i] === '}') {
|
|
245
|
+
d--;
|
|
246
|
+
body[i] = ' ';
|
|
247
|
+
}
|
|
248
|
+
else if (d > 0 && body[i] !== '\n')
|
|
249
|
+
body[i] = ' ';
|
|
250
|
+
}
|
|
251
|
+
let bodyText = body.join('');
|
|
252
|
+
bodyText = bodyText.replace(/\|\s*[\w\s,&:()]*?\s*\|\s*[^;{}]*/g, ' ');
|
|
253
|
+
if (!/(?<![\w.#])(?:return\b|panic\s*!|unreachable\s*!|bail\s*!|(?:std\s*::\s*)?process\s*::\s*exit\s*\()/.test(bodyText))
|
|
254
|
+
continue;
|
|
255
|
+
// Credit region: after the guard block to the end of the enclosing block.
|
|
256
|
+
let end = masked.length;
|
|
257
|
+
for (let i = close + 1, d = 0; i < masked.length; i++) {
|
|
258
|
+
if (masked[i] === '{')
|
|
259
|
+
d++;
|
|
260
|
+
else if (masked[i] === '}' && --d < 0) {
|
|
261
|
+
end = i;
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// Is the guarded binding a `&mut` parameter of the enclosing function?
|
|
266
|
+
let mutParam = false;
|
|
267
|
+
{
|
|
268
|
+
const before = masked.slice(0, at);
|
|
269
|
+
let fnOpen = -1;
|
|
270
|
+
for (const m of before.matchAll(/\bfn\s+\w+\s*(?:<[^>]*>)?\s*\(/g))
|
|
271
|
+
fnOpen = m.index + m[0].length - 1;
|
|
272
|
+
if (fnOpen >= 0) {
|
|
273
|
+
let depth = 1, fnClose = -1;
|
|
274
|
+
for (let i = fnOpen + 1; i < at; i++) {
|
|
275
|
+
if (masked[i] === '(')
|
|
276
|
+
depth++;
|
|
277
|
+
else if (masked[i] === ')' && --depth === 0) {
|
|
278
|
+
fnClose = i;
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (fnClose > fnOpen) {
|
|
283
|
+
const params = masked.slice(fnOpen + 1, fnClose);
|
|
284
|
+
mutParam = new RegExp(String.raw `\b${name}\s*:\s*&(?:\s*'\w+)?\s*mut\b`).test(params);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// Could the binding be `mut`? Any `mut name` / `name: &mut` before the
|
|
289
|
+
// guard counts (wider than needed, which only ends the credit sooner).
|
|
290
|
+
const mutBinding = mutParam || new RegExp(String.raw `\bmut\s+${name}\b|\b${name}\s*:\s*&(?:\s*'\w+)?\s*mut\b`).test(masked.slice(0, at));
|
|
291
|
+
// Whole lines after the guard's closing line, up to the line before the
|
|
292
|
+
// enclosing block's closing brace (or the end of the file).
|
|
293
|
+
const firstLine = lineOf(close) + 1;
|
|
294
|
+
const lastLine = end === masked.length ? origLines.length - 1 : lineOf(end) - 1;
|
|
295
|
+
let stop = lastLine + 1;
|
|
296
|
+
// A rebind or mutation ends the credit (scanned over the whole region, so a
|
|
297
|
+
// pattern or parameter list wrapped over lines is seen in one piece);
|
|
298
|
+
// inside a later loop it ends at the loop.
|
|
299
|
+
let rebindLine = lastLine + 1;
|
|
300
|
+
const rb = firstRebind(masked, close + 1, end, name, { mutBinding });
|
|
301
|
+
if (rb >= 0)
|
|
302
|
+
rebindLine = lineOf(rb);
|
|
303
|
+
if (mutParam) {
|
|
304
|
+
for (let l = firstLine; l < rebindLine && l <= lastLine; l++) {
|
|
305
|
+
if (passesMutParam(maskedLines[l], name)) {
|
|
306
|
+
rebindLine = l;
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (rebindLine <= lastLine) {
|
|
312
|
+
const l = rebindLine;
|
|
313
|
+
stop = l;
|
|
314
|
+
for (const lp of masked.slice(close + 1, end).matchAll(/\b(?:for|while|loop)\b[^{;]*\{/g)) {
|
|
315
|
+
const lpOpen = close + 1 + lp.index + lp[0].length - 1;
|
|
316
|
+
const lpClose = matchBrace(masked, lpOpen);
|
|
317
|
+
const lpLine = lineOf(lpOpen);
|
|
318
|
+
if (lpClose >= 0 && lineOf(lpClose) >= l && lpLine <= l)
|
|
319
|
+
stop = Math.min(stop, lpLine);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
const mention = new RegExp(String.raw `(?<![\w.])${name}\b`);
|
|
323
|
+
for (let l = firstLine; l < stop && l <= lastLine; l++) {
|
|
324
|
+
if (!mention.test(maskedLines[l]))
|
|
325
|
+
continue;
|
|
326
|
+
// Evaluate "reads another value" over the whole statement that contains
|
|
327
|
+
// this mention (up to a terminating `;` or the matching close of the
|
|
328
|
+
// enclosing call), not only the single line the name sits on.
|
|
329
|
+
// The line itself is checked too, so a second statement on the same
|
|
330
|
+
// line (`a(tool); b(other);`) also ends the credit for that line.
|
|
331
|
+
const stmt = statementSpan(code, masked, lineStarts[l], end);
|
|
332
|
+
if (readsOtherValue(stmt.orig, stmt.masked, name))
|
|
333
|
+
continue;
|
|
334
|
+
if (readsOtherValue(origLines[l], maskedLines[l], name))
|
|
335
|
+
continue;
|
|
336
|
+
out.push({
|
|
337
|
+
type: 'rust_literal_equality_guard',
|
|
338
|
+
method: 'guard',
|
|
339
|
+
line: l + 1,
|
|
340
|
+
sanitizes: CREDITED_TYPES,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return out;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Exact text of the statement that contains `lineStart` (absolute index),
|
|
348
|
+
* clipped to `endIdx`. Walks back to the previous `;` / `{` / `}` at depth 0
|
|
349
|
+
* and forward to a terminating `;` (or unmatched closer), so a multi-line
|
|
350
|
+
* `format!(…, tool, extra)` is considered as one statement without pulling in
|
|
351
|
+
* the enclosing function signature.
|
|
352
|
+
*/
|
|
353
|
+
function statementSpan(code, masked, lineStart, endIdx) {
|
|
354
|
+
// Walk back to the previous statement boundary at bracket depth 0.
|
|
355
|
+
let start = lineStart;
|
|
356
|
+
let depth = 0;
|
|
357
|
+
for (let i = lineStart - 1; i >= 0; i--) {
|
|
358
|
+
const ch = masked[i];
|
|
359
|
+
if (ch === ')' || ch === ']')
|
|
360
|
+
depth++;
|
|
361
|
+
else if (ch === '(' || ch === '[') {
|
|
362
|
+
if (depth === 0) {
|
|
363
|
+
start = i + 1;
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
depth--;
|
|
367
|
+
}
|
|
368
|
+
else if (ch === '}') {
|
|
369
|
+
if (depth === 0) {
|
|
370
|
+
start = i + 1;
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
depth++; // matching an earlier `{` when walking back through nested blocks
|
|
374
|
+
}
|
|
375
|
+
else if (ch === '{') {
|
|
376
|
+
if (depth === 0) {
|
|
377
|
+
start = i + 1;
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
depth--;
|
|
381
|
+
}
|
|
382
|
+
else if (ch === ';' && depth === 0) {
|
|
383
|
+
start = i + 1;
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
if (i === 0)
|
|
387
|
+
start = 0;
|
|
388
|
+
}
|
|
389
|
+
// Walk forward to terminating `;` at depth 0, or stop at `endIdx` / unmatched `}`.
|
|
390
|
+
depth = 0;
|
|
391
|
+
let stop = Math.min(endIdx, masked.length);
|
|
392
|
+
for (let i = start; i < stop; i++) {
|
|
393
|
+
const ch = masked[i];
|
|
394
|
+
if (ch === '(' || ch === '[')
|
|
395
|
+
depth++;
|
|
396
|
+
else if (ch === ')' || ch === ']') {
|
|
397
|
+
if (depth === 0) {
|
|
398
|
+
stop = i;
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
depth--;
|
|
402
|
+
}
|
|
403
|
+
else if (ch === '{')
|
|
404
|
+
depth++;
|
|
405
|
+
else if (ch === '}') {
|
|
406
|
+
if (depth === 0) {
|
|
407
|
+
stop = i;
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
depth--;
|
|
411
|
+
}
|
|
412
|
+
else if (ch === ';' && depth === 0) {
|
|
413
|
+
stop = i + 1;
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
return {
|
|
418
|
+
orig: code.slice(start, stop),
|
|
419
|
+
masked: masked.slice(start, stop),
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=rust-literal-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rust-literal-guard.js","sourceRoot":"","sources":["../../src/analysis/rust-literal-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scalar-derivation taint barrier (#568, parent #349).
|
|
3
|
+
*
|
|
4
|
+
* A local whose whole initializer measures or tests a value — its length, a
|
|
5
|
+
* match count, a boolean from a regex test or a containment check — holds an
|
|
6
|
+
* integer or a boolean. That value carries the magnitude of the input, not
|
|
7
|
+
* its content, so it cannot deliver a string payload to an injection sink.
|
|
8
|
+
*
|
|
9
|
+
* This is a type rule, not sanitizer credit for the call: a string-returning
|
|
10
|
+
* matcher (`re.FindString(text)`, `text.match(re)`) still propagates taint.
|
|
11
|
+
* Numeric parses (`strconv.Atoi`, `parseInt`) are not covered here; a parsed
|
|
12
|
+
* number is attacker-chosen and stays tainted for size-sensitive consumers.
|
|
13
|
+
*
|
|
14
|
+
* The test reads the definition's own line. An initializer that is not a
|
|
15
|
+
* single complete expression on that line is not credited.
|
|
16
|
+
*/
|
|
17
|
+
import type { DFGDef } from '../types/index.js';
|
|
18
|
+
/** True when `rhs` is a whole-expression measure or test of a value. */
|
|
19
|
+
export declare function isScalarDerivation(rhs: string, language: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* DFG def ids whose value is an integer or boolean derived from another value
|
|
22
|
+
* by a whole-expression measure or test. Taint does not flow into these defs.
|
|
23
|
+
*/
|
|
24
|
+
export declare function scalarDerivedDefIds(defs: readonly DFGDef[], code: string, language: string): Set<number>;
|
|
25
|
+
/**
|
|
26
|
+
* DFG def ids of a Go local initialised by `make(<type>, <len>[, <cap>])` whose
|
|
27
|
+
* every size argument is an integer literal or a variable rejected above a
|
|
28
|
+
* constant earlier in the same function (`if n > K { return }`). The buffer
|
|
29
|
+
* holds zero values; its size is bounded, so the request text that chose the
|
|
30
|
+
* size does not reach a sink through it. An unbounded size is not credited.
|
|
31
|
+
*/
|
|
32
|
+
export declare function boundedMakeDefIds(defs: readonly DFGDef[], code: string, language: string): Set<number>;
|
|
33
|
+
//# sourceMappingURL=scalar-derivation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scalar-derivation.d.ts","sourceRoot":"","sources":["../../src/analysis/scalar-derivation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAyGhD,wEAAwE;AACxE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAkBzE;AAgBD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAaxG;AA0ID;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAsBtG"}
|