circle-ir 3.51.0 → 3.53.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.
Files changed (35) hide show
  1. package/configs/sinks/path.yaml +0 -16
  2. package/configs/sources/file_sources.yaml +32 -0
  3. package/dist/analysis/config-loader.d.ts.map +1 -1
  4. package/dist/analysis/config-loader.js +17 -20
  5. package/dist/analysis/config-loader.js.map +1 -1
  6. package/dist/analysis/passes/insecure-cookie-pass.d.ts +23 -23
  7. package/dist/analysis/passes/insecure-cookie-pass.d.ts.map +1 -1
  8. package/dist/analysis/passes/insecure-cookie-pass.js +169 -79
  9. package/dist/analysis/passes/insecure-cookie-pass.js.map +1 -1
  10. package/dist/analysis/passes/tls-verify-disabled-pass.d.ts +52 -0
  11. package/dist/analysis/passes/tls-verify-disabled-pass.d.ts.map +1 -0
  12. package/dist/analysis/passes/tls-verify-disabled-pass.js +247 -0
  13. package/dist/analysis/passes/tls-verify-disabled-pass.js.map +1 -0
  14. package/dist/analysis/passes/weak-crypto-pass.d.ts +59 -0
  15. package/dist/analysis/passes/weak-crypto-pass.d.ts.map +1 -0
  16. package/dist/analysis/passes/weak-crypto-pass.js +392 -0
  17. package/dist/analysis/passes/weak-crypto-pass.js.map +1 -0
  18. package/dist/analysis/passes/weak-hash-pass.d.ts +45 -0
  19. package/dist/analysis/passes/weak-hash-pass.d.ts.map +1 -0
  20. package/dist/analysis/passes/weak-hash-pass.js +150 -0
  21. package/dist/analysis/passes/weak-hash-pass.js.map +1 -0
  22. package/dist/analysis/passes/weak-random-pass.d.ts +53 -0
  23. package/dist/analysis/passes/weak-random-pass.d.ts.map +1 -0
  24. package/dist/analysis/passes/weak-random-pass.js +181 -0
  25. package/dist/analysis/passes/weak-random-pass.js.map +1 -0
  26. package/dist/analysis/taint-matcher.d.ts.map +1 -1
  27. package/dist/analysis/taint-matcher.js +28 -13
  28. package/dist/analysis/taint-matcher.js.map +1 -1
  29. package/dist/analyzer.d.ts.map +1 -1
  30. package/dist/analyzer.js +12 -0
  31. package/dist/analyzer.js.map +1 -1
  32. package/dist/browser/circle-ir.js +852 -57
  33. package/dist/core/circle-ir-core.cjs +25 -26
  34. package/dist/core/circle-ir-core.js +25 -26
  35. package/package.json +1 -1
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Pass: tls-verify-disabled (CWE-295, category: security)
3
+ *
4
+ * Pattern pass — flags places where TLS certificate / hostname verification
5
+ * is explicitly disabled. This is a *configuration* vulnerability (the bad
6
+ * value is hard-coded, no taint flow is involved).
7
+ *
8
+ * Detection per language:
9
+ * Go:
10
+ * - `&tls.Config{InsecureSkipVerify: true}` (composite literal)
11
+ * - Detected via call argument scan: when the receiver is `tls` and
12
+ * call/composite contains literal `InsecureSkipVerify: true`, OR via
13
+ * a syntactic text scan (composite literals are not always emitted
14
+ * as calls in IR).
15
+ * Python:
16
+ * - `requests.get|post|put|delete|patch|head|options|request(..., verify=False)`
17
+ * - `ssl._create_unverified_context()` / `ssl._create_default_https_context = ssl._create_unverified_context`
18
+ * - `urllib3.disable_warnings(InsecureRequestWarning)` — best-effort hint
19
+ * - `httpx.Client(verify=False)` / `httpx.get(..., verify=False)`
20
+ * JavaScript / TypeScript:
21
+ * - `{ rejectUnauthorized: false }` in https.request / fetch options /
22
+ * node-fetch / axios — text scan on arg expressions
23
+ * - `https.Agent({ rejectUnauthorized: false })`
24
+ * - `process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'` (assignment;
25
+ * detected via call to property assignment — best-effort)
26
+ * Java:
27
+ * - Custom `HostnameVerifier` that returns true unconditionally
28
+ * (lambdas `(h, s) -> true` / anonymous classes) — detected via
29
+ * textual scan on setHostnameVerifier arg expression.
30
+ * - `setHostnameVerifier(NoopHostnameVerifier.INSTANCE)` /
31
+ * `setHostnameVerifier(new AllowAllHostnameVerifier())`
32
+ *
33
+ * Aligned with: gosec G402 (Go), Bandit B501/B502/B504/B505 (Python).
34
+ */
35
+ // Python HTTP libraries whose calls accept a verify=False kwarg.
36
+ const PY_HTTP_METHODS = new Set([
37
+ 'get', 'post', 'put', 'delete', 'patch', 'head', 'options', 'request',
38
+ 'send',
39
+ ]);
40
+ const PY_HTTP_RECEIVERS = new Set([
41
+ 'requests', 'httpx',
42
+ ]);
43
+ const VERIFY_FALSE_RE = /\bverify\s*=\s*False\b/;
44
+ const REJECT_UNAUTHORIZED_FALSE_RE = /\brejectUnauthorized\s*:\s*false\b/;
45
+ const INSECURE_SKIP_VERIFY_TRUE_RE = /\bInsecureSkipVerify\s*:\s*true\b/;
46
+ const HOSTNAME_LAMBDA_TRUE_RE = /\(\s*\w+\s*,\s*\w+\s*\)\s*->\s*true\b/;
47
+ const ALLOW_ALL_HOSTNAME_VERIFIERS = new Set([
48
+ 'NoopHostnameVerifier.INSTANCE',
49
+ 'new AllowAllHostnameVerifier()',
50
+ 'new NoopHostnameVerifier()',
51
+ ]);
52
+ export class TlsVerifyDisabledPass {
53
+ name = 'tls-verify-disabled';
54
+ category = 'security';
55
+ run(ctx) {
56
+ const { graph, language, code } = ctx;
57
+ const file = graph.ir.meta.file;
58
+ const findings = [];
59
+ // Call-based detection (most precise — uses arg.expression text).
60
+ for (const call of graph.ir.calls) {
61
+ const det = this.detectCall(call, language);
62
+ if (!det)
63
+ continue;
64
+ const line = call.location.line;
65
+ findings.push({ line, language, ...det });
66
+ ctx.addFinding({
67
+ id: `${this.name}-${file}-${line}-${det.pattern}`,
68
+ pass: this.name,
69
+ category: this.category,
70
+ rule_id: this.name,
71
+ cwe: 'CWE-295',
72
+ severity: 'high',
73
+ level: 'error',
74
+ message: `TLS certificate verification disabled via \`${det.pattern}\` in ` +
75
+ `\`${det.api}\`. The connection becomes vulnerable to active ` +
76
+ 'man-in-the-middle attacks — any attacker on the network path can ' +
77
+ 'present a forged certificate.',
78
+ file,
79
+ line,
80
+ fix: this.fixFor(language, det.pattern),
81
+ evidence: { ...det, language },
82
+ });
83
+ }
84
+ // Source-text scan for composite-literal / module-level patterns that
85
+ // do not surface as IR calls (Go `tls.Config{}`, Python ssl globals,
86
+ // Node `NODE_TLS_REJECT_UNAUTHORIZED`).
87
+ for (const extra of this.detectSourceText(code, language)) {
88
+ const dupKey = `${extra.line}-${extra.pattern}`;
89
+ if (findings.some((f) => `${f.line}-${f.pattern}` === dupKey))
90
+ continue;
91
+ findings.push({ ...extra, language });
92
+ ctx.addFinding({
93
+ id: `${this.name}-${file}-${extra.line}-${extra.pattern}`,
94
+ pass: this.name,
95
+ category: this.category,
96
+ rule_id: this.name,
97
+ cwe: 'CWE-295',
98
+ severity: 'high',
99
+ level: 'error',
100
+ message: `TLS certificate verification disabled via \`${extra.pattern}\` ` +
101
+ `(${extra.api}). Vulnerable to active man-in-the-middle.`,
102
+ file,
103
+ line: extra.line,
104
+ fix: this.fixFor(language, extra.pattern),
105
+ evidence: { ...extra, language },
106
+ });
107
+ }
108
+ return { findings };
109
+ }
110
+ detectCall(call, language) {
111
+ const method = call.method_name;
112
+ const receiver = call.receiver ?? '';
113
+ if (language === 'python') {
114
+ // requests.get(..., verify=False) etc.
115
+ if (PY_HTTP_RECEIVERS.has(receiver) && PY_HTTP_METHODS.has(method)) {
116
+ for (const arg of call.arguments) {
117
+ const expr = (arg.expression ?? '').trim();
118
+ if (VERIFY_FALSE_RE.test(expr)) {
119
+ return { pattern: 'verify=False', api: `${receiver}.${method}` };
120
+ }
121
+ }
122
+ }
123
+ // ssl._create_unverified_context()
124
+ if (method === '_create_unverified_context' && receiver === 'ssl') {
125
+ return { pattern: 'ssl._create_unverified_context', api: 'ssl._create_unverified_context()' };
126
+ }
127
+ // httpx.Client(verify=False) — same shape via constructor; receiver is module.
128
+ if (receiver === 'httpx' && method === 'Client') {
129
+ for (const arg of call.arguments) {
130
+ if (VERIFY_FALSE_RE.test(arg.expression ?? '')) {
131
+ return { pattern: 'verify=False', api: 'httpx.Client' };
132
+ }
133
+ }
134
+ }
135
+ return null;
136
+ }
137
+ if (language === 'javascript' || language === 'typescript') {
138
+ // axios.create({httpsAgent: new https.Agent({rejectUnauthorized: false})}),
139
+ // https.request({rejectUnauthorized: false}, ...), fetch(url, {agent: ...})
140
+ // We do an arg-expression text scan because the option commonly appears
141
+ // inside an inline object literal.
142
+ //
143
+ // The JS plugin sometimes surfaces `new https.Agent(...)` with
144
+ // method_name='https.Agent' and receiver=null (rather than receiver='https',
145
+ // method='Agent'). Accept the trailing segment of the dotted name too.
146
+ const lastSeg = method.includes('.') ? method.split('.').pop() ?? '' : method;
147
+ const arglooks = method === 'request' || method === 'get' || method === 'post' ||
148
+ method === 'create' || method === 'Agent' || method === 'fetch' ||
149
+ lastSeg === 'Agent' || lastSeg === 'request' || lastSeg === 'create';
150
+ if (arglooks) {
151
+ for (const arg of call.arguments) {
152
+ if (REJECT_UNAUTHORIZED_FALSE_RE.test(arg.expression ?? '')) {
153
+ return { pattern: 'rejectUnauthorized: false', api: `${receiver || '(global)'}.${method}` };
154
+ }
155
+ }
156
+ }
157
+ return null;
158
+ }
159
+ if (language === 'java') {
160
+ // someConn.setHostnameVerifier((h, s) -> true)
161
+ if (method === 'setHostnameVerifier') {
162
+ const arg = call.arguments.find((a) => a.position === 0);
163
+ const expr = (arg?.expression ?? '').trim();
164
+ if (HOSTNAME_LAMBDA_TRUE_RE.test(expr)) {
165
+ return { pattern: '(h,s) -> true', api: 'setHostnameVerifier' };
166
+ }
167
+ for (const v of ALLOW_ALL_HOSTNAME_VERIFIERS) {
168
+ if (expr === v || expr.replace(/\s+/g, '') === v.replace(/\s+/g, '')) {
169
+ return { pattern: v, api: 'setHostnameVerifier' };
170
+ }
171
+ }
172
+ }
173
+ return null;
174
+ }
175
+ return null;
176
+ }
177
+ detectSourceText(code, language) {
178
+ const out = [];
179
+ const lines = code.split('\n');
180
+ if (language === 'go') {
181
+ // Look for `InsecureSkipVerify: true` literal anywhere — overwhelmingly
182
+ // appears in tls.Config{} composite literals.
183
+ for (let i = 0; i < lines.length; i++) {
184
+ if (INSECURE_SKIP_VERIFY_TRUE_RE.test(lines[i])) {
185
+ out.push({
186
+ line: i + 1,
187
+ pattern: 'InsecureSkipVerify: true',
188
+ api: 'tls.Config',
189
+ });
190
+ }
191
+ }
192
+ }
193
+ if (language === 'python') {
194
+ for (let i = 0; i < lines.length; i++) {
195
+ const l = lines[i];
196
+ if (/ssl\._create_default_https_context\s*=\s*ssl\._create_unverified_context/.test(l)) {
197
+ out.push({
198
+ line: i + 1,
199
+ pattern: 'ssl._create_default_https_context = _create_unverified_context',
200
+ api: 'ssl module override',
201
+ });
202
+ }
203
+ }
204
+ }
205
+ if (language === 'javascript' || language === 'typescript') {
206
+ for (let i = 0; i < lines.length; i++) {
207
+ const l = lines[i];
208
+ if (/process\.env\.NODE_TLS_REJECT_UNAUTHORIZED\s*=\s*['"]0['"]/.test(l)) {
209
+ out.push({
210
+ line: i + 1,
211
+ pattern: 'NODE_TLS_REJECT_UNAUTHORIZED=0',
212
+ api: 'process.env',
213
+ });
214
+ }
215
+ }
216
+ }
217
+ return out;
218
+ }
219
+ fixFor(language, pattern) {
220
+ if (pattern.includes('InsecureSkipVerify')) {
221
+ return 'Remove `InsecureSkipVerify: true` — let Go verify the cert. If ' +
222
+ 'you need to trust a private CA, set `RootCAs` to a `*x509.CertPool` ' +
223
+ 'containing that CA.';
224
+ }
225
+ if (pattern.includes('verify=False')) {
226
+ return 'Remove `verify=False`. To trust a private CA, pass `verify=\'/path/to/ca.pem\'`.';
227
+ }
228
+ if (pattern.includes('rejectUnauthorized')) {
229
+ return 'Remove `rejectUnauthorized: false`. To trust a private CA, set the ' +
230
+ '`ca` option to the CA cert(s). Never disable TLS verification globally.';
231
+ }
232
+ if (pattern.includes('NODE_TLS_REJECT_UNAUTHORIZED')) {
233
+ return 'Remove the `NODE_TLS_REJECT_UNAUTHORIZED=0` assignment — it globally ' +
234
+ 'disables TLS verification for every outbound HTTPS request.';
235
+ }
236
+ if (language === 'java') {
237
+ return 'Do not use an always-true HostnameVerifier or AllowAllHostnameVerifier. ' +
238
+ 'Use the JVM\'s default verifier; for self-signed certs add the cert to a ' +
239
+ 'custom TrustManager that validates the chain.';
240
+ }
241
+ if (pattern.includes('ssl._create_unverified_context')) {
242
+ return 'Do not use `_create_unverified_context()`. Use `ssl.create_default_context()`.';
243
+ }
244
+ return 'Restore TLS certificate and hostname verification.';
245
+ }
246
+ }
247
+ //# sourceMappingURL=tls-verify-disabled-pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tls-verify-disabled-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/tls-verify-disabled-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAKH,iEAAiE;AACjE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS;IACrE,MAAM;CACP,CAAC,CAAC;AACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,UAAU,EAAE,OAAO;CACpB,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,wBAAwB,CAAC;AACjD,MAAM,4BAA4B,GAAG,oCAAoC,CAAC;AAC1E,MAAM,4BAA4B,GAAG,mCAAmC,CAAC;AACzE,MAAM,uBAAuB,GAAG,uCAAuC,CAAC;AACxE,MAAM,4BAA4B,GAAG,IAAI,GAAG,CAAC;IAC3C,+BAA+B;IAC/B,gCAAgC;IAChC,4BAA4B;CAC7B,CAAC,CAAC;AAWH,MAAM,OAAO,qBAAqB;IACvB,IAAI,GAAG,qBAAqB,CAAC;IAC7B,QAAQ,GAAG,UAAmB,CAAC;IAExC,GAAG,CAAC,GAAgB;QAClB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;QAChC,MAAM,QAAQ,GAAwC,EAAE,CAAC;QAEzD,kEAAkE;QAClE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAClC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC5C,IAAI,CAAC,GAAG;gBAAE,SAAS;YAEnB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;YAE1C,GAAG,CAAC,UAAU,CAAC;gBACb,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE;gBACjD,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,IAAI;gBAClB,GAAG,EAAE,SAAS;gBACd,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,OAAO;gBACd,OAAO,EACL,+CAA+C,GAAG,CAAC,OAAO,QAAQ;oBAClE,KAAK,GAAG,CAAC,GAAG,kDAAkD;oBAC9D,mEAAmE;oBACnE,+BAA+B;gBACjC,IAAI;gBACJ,IAAI;gBACJ,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;gBACvC,QAAQ,EAAE,EAAE,GAAG,GAAG,EAAE,QAAQ,EAAE;aAC/B,CAAC,CAAC;QACL,CAAC;QAED,sEAAsE;QACtE,qEAAqE;QACrE,wCAAwC;QACxC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC1D,MAAM,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAChD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,MAAM,CAAC;gBAAE,SAAS;YACxE,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACtC,GAAG,CAAC,UAAU,CAAC;gBACb,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,EAAE;gBACzD,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,IAAI;gBAClB,GAAG,EAAE,SAAS;gBACd,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,OAAO;gBACd,OAAO,EACL,+CAA+C,KAAK,CAAC,OAAO,KAAK;oBACjE,IAAI,KAAK,CAAC,GAAG,4CAA4C;gBAC3D,IAAI;gBACJ,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC;gBACzC,QAAQ,EAAE,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE;aACjC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,CAAC;IACtB,CAAC;IAEO,UAAU,CAAC,IAAc,EAAE,QAAgB;QAIjD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;QAErC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,uCAAuC;YACvC,IAAI,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnE,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACjC,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;oBAC3C,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC/B,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,QAAQ,IAAI,MAAM,EAAE,EAAE,CAAC;oBACnE,CAAC;gBACH,CAAC;YACH,CAAC;YACD,mCAAmC;YACnC,IAAI,MAAM,KAAK,4BAA4B,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;gBAClE,OAAO,EAAE,OAAO,EAAE,gCAAgC,EAAE,GAAG,EAAE,kCAAkC,EAAE,CAAC;YAChG,CAAC;YACD,+EAA+E;YAC/E,IAAI,QAAQ,KAAK,OAAO,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAChD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACjC,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,CAAC;wBAC/C,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC;oBAC1D,CAAC;gBACH,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC3D,4EAA4E;YAC5E,4EAA4E;YAC5E,wEAAwE;YACxE,mCAAmC;YACnC,EAAE;YACF,+DAA+D;YAC/D,6EAA6E;YAC7E,uEAAuE;YACvE,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YAC9E,MAAM,QAAQ,GACZ,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM;gBAC7D,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,OAAO;gBAC/D,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,QAAQ,CAAC;YACvE,IAAI,QAAQ,EAAE,CAAC;gBACb,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACjC,IAAI,4BAA4B,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,CAAC;wBAC5D,OAAO,EAAE,OAAO,EAAE,2BAA2B,EAAE,GAAG,EAAE,GAAG,QAAQ,IAAI,UAAU,IAAI,MAAM,EAAE,EAAE,CAAC;oBAC9F,CAAC;gBACH,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YACxB,+CAA+C;YAC/C,IAAI,MAAM,KAAK,qBAAqB,EAAE,CAAC;gBACrC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC;gBACzD,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC5C,IAAI,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACvC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,qBAAqB,EAAE,CAAC;gBAClE,CAAC;gBACD,KAAK,MAAM,CAAC,IAAI,4BAA4B,EAAE,CAAC;oBAC7C,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;wBACrE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,qBAAqB,EAAE,CAAC;oBACpD,CAAC;gBACH,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,gBAAgB,CAAC,IAAY,EAAE,QAAgB;QAGrD,MAAM,GAAG,GAA0D,EAAE,CAAC;QACtE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/B,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,wEAAwE;YACxE,8CAA8C;YAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,IAAI,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAChD,GAAG,CAAC,IAAI,CAAC;wBACP,IAAI,EAAE,CAAC,GAAG,CAAC;wBACX,OAAO,EAAE,0BAA0B;wBACnC,GAAG,EAAE,YAAY;qBAClB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACnB,IAAI,0EAA0E,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBACvF,GAAG,CAAC,IAAI,CAAC;wBACP,IAAI,EAAE,CAAC,GAAG,CAAC;wBACX,OAAO,EAAE,gEAAgE;wBACzE,GAAG,EAAE,qBAAqB;qBAC3B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC3D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACnB,IAAI,4DAA4D,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzE,GAAG,CAAC,IAAI,CAAC;wBACP,IAAI,EAAE,CAAC,GAAG,CAAC;wBACX,OAAO,EAAE,gCAAgC;wBACzC,GAAG,EAAE,aAAa;qBACnB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,MAAM,CAAC,QAAgB,EAAE,OAAe;QAC9C,IAAI,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAC3C,OAAO,iEAAiE;gBACtE,sEAAsE;gBACtE,qBAAqB,CAAC;QAC1B,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YACrC,OAAO,kFAAkF,CAAC;QAC5F,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAC3C,OAAO,qEAAqE;gBAC1E,yEAAyE,CAAC;QAC9E,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAAC,EAAE,CAAC;YACrD,OAAO,uEAAuE;gBAC5E,6DAA6D,CAAC;QAClE,CAAC;QACD,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YACxB,OAAO,0EAA0E;gBAC/E,2EAA2E;gBAC3E,+CAA+C,CAAC;QACpD,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAAC,EAAE,CAAC;YACvD,OAAO,gFAAgF,CAAC;QAC1F,CAAC;QACD,OAAO,oDAAoD,CAAC;IAC9D,CAAC;CACF"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Pass: weak-crypto (CWE-327 / CWE-329 / CWE-321 / CWE-326, category: security)
3
+ *
4
+ * Pattern pass — flags use of cryptographically weak symmetric ciphers
5
+ * (DES, 3DES, RC2, RC4, Blowfish), ECB mode, weak RSA key sizes (< 2048),
6
+ * static/zero IVs (CWE-329), hardcoded symmetric keys (CWE-321), and weak
7
+ * AES modes. Like weak-hash, the vulnerability is the *constant algorithm
8
+ * string*, *constant IV bytes*, *literal key material*, or *key-size
9
+ * argument*, not data flow.
10
+ *
11
+ * Detection per language:
12
+ * Java:
13
+ * - `Cipher.getInstance("DES"|"DES/...")` / `"RC4"` / `"RC2"` / `"Blowfish"`
14
+ * - `Cipher.getInstance(".../ECB/...")` — ECB mode
15
+ * - `KeyGenerator.getInstance("DES"|"RC4"|"Blowfish")`
16
+ * - `new IvParameterSpec(new byte[N])` / `new IvParameterSpec(literalBytes)`
17
+ * — static/zero IV (CWE-329, issue #87)
18
+ * - `new SecretKeySpec("literal".getBytes(), ...)` — hardcoded symmetric
19
+ * key (CWE-321, issue #87)
20
+ * - `KeyPairGenerator.initialize(<2048)` — weak RSA key size (CWE-326,
21
+ * issue #87). Detected by literal `< 2048` argument on `initialize`
22
+ * calls whose receiver is a `KeyPairGenerator` (best-effort: matches
23
+ * any `*.initialize(int)` where the literal is below 2048, since
24
+ * 2048+ is also the minimum for DSA / DH and 256+ is correct for EC).
25
+ * Python:
26
+ * - `Crypto.Cipher.DES.new(...)` / `Crypto.Cipher.ARC4.new(...)` /
27
+ * `Crypto.Cipher.Blowfish.new(...)` (pycryptodome / pycrypto)
28
+ * - `cryptography.hazmat.primitives.ciphers.algorithms.{TripleDES,Blowfish,ARC4,IDEA,SEED,CAST5}`
29
+ * - `AES.new(key, AES.MODE_ECB)` — ECB mode argument
30
+ * JavaScript / TypeScript:
31
+ * - `crypto.createCipher(...)` (deprecated; always weak)
32
+ * - `crypto.createCipheriv("des-..."|"rc4"|"bf-..."|"des-ede"|".*-ecb")`
33
+ * Go:
34
+ * - `des.NewCipher(...)` / `des.NewTripleDESCipher(...)` / `rc4.NewCipher(...)`
35
+ * (from `crypto/des` and `crypto/rc4`)
36
+ * - `cipher.NewECBEncrypter(...)` (custom ECB wrappers — best-effort)
37
+ *
38
+ * Aligned with: gosec G401/G405, Bandit B304/B305/B306, OWASP Benchmark `crypto` category.
39
+ */
40
+ import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js';
41
+ export type WeakCryptoIssue = 'weak-cipher' | 'ecb-mode' | 'deprecated-api' | 'static-iv' | 'hardcoded-key' | 'weak-rsa-key';
42
+ export interface WeakCryptoResult {
43
+ findings: Array<{
44
+ line: number;
45
+ language: string;
46
+ issue: WeakCryptoIssue;
47
+ detail: string;
48
+ api: string;
49
+ }>;
50
+ }
51
+ export declare class WeakCryptoPass implements AnalysisPass<WeakCryptoResult> {
52
+ readonly name = "weak-crypto";
53
+ readonly category: "security";
54
+ run(ctx: PassContext): WeakCryptoResult;
55
+ private buildMessage;
56
+ private buildFix;
57
+ private detect;
58
+ }
59
+ //# sourceMappingURL=weak-crypto-pass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weak-crypto-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/weak-crypto-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAkI9E,MAAM,MAAM,eAAe,GACvB,aAAa,GACb,UAAU,GACV,gBAAgB,GAChB,WAAW,GACX,eAAe,GACf,cAAc,CAAC;AAYnB,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,eAAe,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;KACb,CAAC,CAAC;CACJ;AAED,qBAAa,cAAe,YAAW,YAAY,CAAC,gBAAgB,CAAC;IACnE,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,gBAAgB;IAgCvC,OAAO,CAAC,YAAY;IA0CpB,OAAO,CAAC,QAAQ;IA2BhB,OAAO,CAAC,MAAM;CAqJf"}