@quantakrypto/core 0.4.1 → 0.4.3

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 (140) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +38 -10
  3. package/dist/agent-types.js.map +1 -1
  4. package/dist/baseline.js.map +1 -1
  5. package/dist/cache.js.map +1 -1
  6. package/dist/cbom.d.ts.map +1 -1
  7. package/dist/cbom.js +13 -4
  8. package/dist/cbom.js.map +1 -1
  9. package/dist/changed.js.map +1 -1
  10. package/dist/codemods/config-toggle.js.map +1 -1
  11. package/dist/codemods/registry.js.map +1 -1
  12. package/dist/comments.d.ts +26 -0
  13. package/dist/comments.d.ts.map +1 -1
  14. package/dist/comments.js +141 -1
  15. package/dist/comments.js.map +1 -1
  16. package/dist/config.js.map +1 -1
  17. package/dist/cwe.js.map +1 -1
  18. package/dist/dependencies.d.ts +3 -2
  19. package/dist/dependencies.d.ts.map +1 -1
  20. package/dist/dependencies.js +151 -4
  21. package/dist/dependencies.js.map +1 -1
  22. package/dist/detect-utils.d.ts +14 -3
  23. package/dist/detect-utils.d.ts.map +1 -1
  24. package/dist/detect-utils.js +32 -4
  25. package/dist/detect-utils.js.map +1 -1
  26. package/dist/detectors/c.d.ts.map +1 -1
  27. package/dist/detectors/c.js +190 -2
  28. package/dist/detectors/c.js.map +1 -1
  29. package/dist/detectors/csharp.d.ts.map +1 -1
  30. package/dist/detectors/csharp.js +141 -3
  31. package/dist/detectors/csharp.js.map +1 -1
  32. package/dist/detectors/go.d.ts +5 -3
  33. package/dist/detectors/go.d.ts.map +1 -1
  34. package/dist/detectors/go.js +187 -3
  35. package/dist/detectors/go.js.map +1 -1
  36. package/dist/detectors/java.d.ts.map +1 -1
  37. package/dist/detectors/java.js +168 -3
  38. package/dist/detectors/java.js.map +1 -1
  39. package/dist/detectors/pem.d.ts.map +1 -1
  40. package/dist/detectors/pem.js +49 -1
  41. package/dist/detectors/pem.js.map +1 -1
  42. package/dist/detectors/python.d.ts.map +1 -1
  43. package/dist/detectors/python.js +74 -3
  44. package/dist/detectors/python.js.map +1 -1
  45. package/dist/detectors/ruby.d.ts +9 -5
  46. package/dist/detectors/ruby.d.ts.map +1 -1
  47. package/dist/detectors/ruby.js +122 -2
  48. package/dist/detectors/ruby.js.map +1 -1
  49. package/dist/detectors/rust.d.ts +8 -3
  50. package/dist/detectors/rust.d.ts.map +1 -1
  51. package/dist/detectors/rust.js +185 -3
  52. package/dist/detectors/rust.js.map +1 -1
  53. package/dist/detectors/source.d.ts.map +1 -1
  54. package/dist/detectors/source.js +131 -13
  55. package/dist/detectors/source.js.map +1 -1
  56. package/dist/detectors/stateful-hbs.d.ts +22 -0
  57. package/dist/detectors/stateful-hbs.d.ts.map +1 -0
  58. package/dist/detectors/stateful-hbs.js +139 -0
  59. package/dist/detectors/stateful-hbs.js.map +1 -0
  60. package/dist/errors.js.map +1 -1
  61. package/dist/evidence.d.ts +48 -0
  62. package/dist/evidence.d.ts.map +1 -0
  63. package/dist/evidence.js +76 -0
  64. package/dist/evidence.js.map +1 -0
  65. package/dist/index.d.ts +4 -2
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +4 -2
  68. package/dist/index.js.map +1 -1
  69. package/dist/inventory.d.ts +2 -0
  70. package/dist/inventory.d.ts.map +1 -1
  71. package/dist/inventory.js +27 -1
  72. package/dist/inventory.js.map +1 -1
  73. package/dist/parallel.js +15 -0
  74. package/dist/parallel.js.map +1 -1
  75. package/dist/patch-policy.js.map +1 -1
  76. package/dist/redact.d.ts.map +1 -1
  77. package/dist/redact.js +122 -7
  78. package/dist/redact.js.map +1 -1
  79. package/dist/registry.d.ts +2 -2
  80. package/dist/registry.d.ts.map +1 -1
  81. package/dist/registry.js +4 -2
  82. package/dist/registry.js.map +1 -1
  83. package/dist/remediate-pipeline.d.ts +3 -0
  84. package/dist/remediate-pipeline.d.ts.map +1 -1
  85. package/dist/remediate-pipeline.js +50 -0
  86. package/dist/remediate-pipeline.js.map +1 -1
  87. package/dist/remediate-request.js.map +1 -1
  88. package/dist/remediation.d.ts +9 -3
  89. package/dist/remediation.d.ts.map +1 -1
  90. package/dist/remediation.js +33 -6
  91. package/dist/remediation.js.map +1 -1
  92. package/dist/report.d.ts +9 -0
  93. package/dist/report.d.ts.map +1 -1
  94. package/dist/report.js +31 -0
  95. package/dist/report.js.map +1 -1
  96. package/dist/scan-worker.js.map +1 -1
  97. package/dist/scan.d.ts.map +1 -1
  98. package/dist/scan.js +16 -2
  99. package/dist/scan.js.map +1 -1
  100. package/dist/severity.js.map +1 -1
  101. package/dist/triage.js.map +1 -1
  102. package/dist/types.d.ts +8 -1
  103. package/dist/types.d.ts.map +1 -1
  104. package/dist/types.js.map +1 -1
  105. package/dist/verify.js.map +1 -1
  106. package/dist/version.d.ts +1 -1
  107. package/dist/version.js +1 -1
  108. package/dist/version.js.map +1 -1
  109. package/dist/walk.js.map +1 -1
  110. package/dist/worktree.d.ts.map +1 -1
  111. package/dist/worktree.js +10 -1
  112. package/dist/worktree.js.map +1 -1
  113. package/package.json +1 -1
  114. package/src/cbom.ts +13 -4
  115. package/src/comments.ts +140 -1
  116. package/src/dependencies.ts +156 -6
  117. package/src/detect-utils.ts +33 -4
  118. package/src/detectors/c.ts +202 -2
  119. package/src/detectors/csharp.ts +154 -3
  120. package/src/detectors/go.ts +209 -6
  121. package/src/detectors/java.ts +189 -3
  122. package/src/detectors/pem.ts +53 -1
  123. package/src/detectors/python.ts +82 -3
  124. package/src/detectors/ruby.ts +138 -7
  125. package/src/detectors/rust.ts +211 -7
  126. package/src/detectors/source.ts +163 -12
  127. package/src/detectors/stateful-hbs.ts +177 -0
  128. package/src/evidence.ts +124 -0
  129. package/src/index.ts +5 -1
  130. package/src/inventory.ts +31 -1
  131. package/src/parallel.ts +15 -0
  132. package/src/redact.ts +125 -8
  133. package/src/registry.ts +4 -2
  134. package/src/remediate-pipeline.ts +55 -0
  135. package/src/remediation.ts +41 -9
  136. package/src/report.ts +41 -2
  137. package/src/scan.ts +21 -2
  138. package/src/types.ts +8 -1
  139. package/src/version.ts +1 -1
  140. package/src/worktree.ts +9 -1
@@ -1,5 +1,5 @@
1
1
  import { JAVA_EXTENSIONS, eachMatch, findingFromRule, hasExtension } from "../detect-utils.js";
2
- import { CWE_BROKEN_CRYPTO } from "../cwe.js";
2
+ import { CWE_BROKEN_CRYPTO, CWE_CERT_VALIDATION, CWE_WEAK_STRENGTH } from "../cwe.js";
3
3
  /* -------------------------------------------------------------------------- */
4
4
  /* Regexes */
5
5
  /* -------------------------------------------------------------------------- */
@@ -8,7 +8,29 @@ import { CWE_BROKEN_CRYPTO } from "../cwe.js";
8
8
  // are symmetric / hashing only).
9
9
  const RE_JAVA_GETINSTANCE = /\b(KeyPairGenerator|Signature|Cipher|KeyAgreement|KeyFactory)\s*\.\s*getInstance\s*\(\s*"([^"]+)"/g;
10
10
  // BouncyCastle lightweight-API class instantiations.
11
- const RE_JAVA_BC = /\bnew\s+(RSAKeyPairGenerator|DSAKeyPairGenerator|ECKeyPairGenerator|ECDSASigner|Ed25519Signer|Ed448Signer|X25519Agreement|X448Agreement)\s*\(/g;
11
+ const RE_JAVA_BC = /\bnew\s+(RSAKeyPairGenerator|DSAKeyPairGenerator|ECKeyPairGenerator|ECDSASigner|Ed25519Signer|Ed448Signer|X25519Agreement|X448Agreement|ECDHBasicAgreement|DHBasicAgreement|X25519KeyPairGenerator|Ed25519KeyPairGenerator|RSAEngine|OAEPEncoding)\s*\(/g;
12
+ // BouncyCastle lightweight-API curve/EdDSA classes as a BARE constructor call —
13
+ // the Kotlin form (`X448KeyPairGenerator()`, no `new` keyword). RE_JAVA_BC above
14
+ // only matches the Java `new <Class>(` form, so Kotlin sources that drive the
15
+ // lightweight API directly are missed. The negative lookbehind `(?<!\bnew\s+)`
16
+ // keeps this additive: `new X448Agreement(` stays with RE_JAVA_BC (java-xdh),
17
+ // while bare `X448Agreement(` routes to the family-specific rules below. Scoped
18
+ // to the exact X448/X25519/Ed448/Ed25519 class names to stay precise.
19
+ const RE_JAVA_BC_CURVE = /(?<!\bnew\s+)\b(X448KeyPairGenerator|X448Agreement|X448PrivateKeyParameters|X25519KeyPairGenerator|X25519Agreement|Ed448KeyPairGenerator|Ed448Signer|Ed25519KeyPairGenerator|Ed25519Signer)\s*\(/g;
20
+ // Insecure JSSE / TLS configuration expressed in Java source. Mirrors the JS
21
+ // tlsDetector in source.ts (category "tls"): a legacy SSL/TLS protocol version
22
+ // requested from SSLContext, and TLS hostname verification neutered via an
23
+ // all-trusting verifier (Apache HttpClient's NoopHostnameVerifier /
24
+ // ALLOW_ALL_HOSTNAME_VERIFIER).
25
+ const RE_JAVA_TLS_LEGACY = /\bSSLContext\s*\.\s*getInstance\s*\(\s*"(SSL|SSLv3|TLSv1)"/g;
26
+ const RE_JAVA_TLS_NOVERIFY = /\b(NoopHostnameVerifier|ALLOW_ALL_HOSTNAME_VERIFIER)\b/g;
27
+ // Identifier-form JWT/JOSE signature algorithms (audit F7). The quoted-string
28
+ // alg token ("RS256") is caught by the language-agnostic jwt-jose detector, but
29
+ // the Java JWT libraries pass the alg as an IDENTIFIER, not a string literal:
30
+ // jjwt's `SignatureAlgorithm.RS256` and auth0 java-jwt's `Algorithm.RSA256` /
31
+ // `Algorithm.ECDSA256`. ("SignatureAlgorithm" has no word boundary before its
32
+ // "Algorithm", so the auth0 branch cannot re-match the jjwt form.)
33
+ const RE_JAVA_JWT_ALG = /\bSignatureAlgorithm\.(?:RS|PS|ES)(?:256|384|512)\b|\bAlgorithm\.(?:RSA|ECDSA)(?:256|384|512)\b/g;
12
34
  /* -------------------------------------------------------------------------- */
13
35
  /* Rule catalog */
14
36
  /* -------------------------------------------------------------------------- */
@@ -105,7 +127,7 @@ const RULE_JAVA_XDH = {
105
127
  title: "Java X25519/X448 key agreement",
106
128
  description: "JCA XDH / X25519 / X448 (KeyPairGenerator / KeyAgreement)",
107
129
  category: "key-exchange",
108
- severity: "low",
130
+ severity: "medium",
109
131
  confidence: "high",
110
132
  algorithm: "X25519",
111
133
  hndl: true,
@@ -124,6 +146,82 @@ const RULE_JAVA_EDDSA = {
124
146
  cwe: CWE_BROKEN_CRYPTO,
125
147
  message: "Ed25519/Ed448 (Java/JCA) is a modern but still classical signature scheme.",
126
148
  };
149
+ // BouncyCastle lightweight-API rules for bare (Kotlin-form) constructor calls.
150
+ // Split by family so X448 and X25519 report their own algorithm string (java-xdh
151
+ // lumps both under "X25519"). Severity/CWE copied from the JCA siblings above.
152
+ const RULE_JAVA_BC_X448 = {
153
+ id: "java-bc-x448",
154
+ title: "Java/Kotlin X448 key agreement (BouncyCastle lightweight API)",
155
+ description: "BouncyCastle X448KeyPairGenerator / X448Agreement / X448PrivateKeyParameters",
156
+ category: "key-exchange",
157
+ severity: "medium",
158
+ confidence: "high",
159
+ algorithm: "X448",
160
+ hndl: true,
161
+ cwe: CWE_BROKEN_CRYPTO,
162
+ message: "X448 (Java/Kotlin, BouncyCastle lightweight API) is modern but still classical key agreement — harvest-now-decrypt-later.",
163
+ };
164
+ const RULE_JAVA_BC_X25519 = {
165
+ id: "java-bc-x25519",
166
+ title: "Java/Kotlin X25519 key agreement (BouncyCastle lightweight API)",
167
+ description: "BouncyCastle X25519KeyPairGenerator / X25519Agreement",
168
+ category: "key-exchange",
169
+ severity: "medium",
170
+ confidence: "high",
171
+ algorithm: "X25519",
172
+ hndl: true,
173
+ cwe: CWE_BROKEN_CRYPTO,
174
+ message: "X25519 (Java/Kotlin, BouncyCastle lightweight API) is modern but still classical key agreement — harvest-now-decrypt-later.",
175
+ };
176
+ const RULE_JAVA_BC_EDDSA = {
177
+ id: "java-bc-eddsa",
178
+ title: "Java/Kotlin Ed25519/Ed448 signature (BouncyCastle lightweight API)",
179
+ description: "BouncyCastle Ed448KeyPairGenerator / Ed448Signer / Ed25519KeyPairGenerator / Ed25519Signer",
180
+ category: "signature",
181
+ severity: "low",
182
+ confidence: "high",
183
+ algorithm: "EdDSA",
184
+ hndl: false,
185
+ cwe: CWE_BROKEN_CRYPTO,
186
+ message: "Ed25519/Ed448 (Java/Kotlin, BouncyCastle lightweight API) is a modern but still classical signature scheme.",
187
+ };
188
+ const RULE_JAVA_TLS_LEGACY = {
189
+ id: "java-tls-legacy-version",
190
+ title: "Legacy SSL/TLS version requested",
191
+ description: 'SSLContext.getInstance("SSL" | "SSLv3" | "TLSv1")',
192
+ category: "tls",
193
+ severity: "medium",
194
+ confidence: "high",
195
+ hndl: false,
196
+ cwe: CWE_WEAK_STRENGTH,
197
+ message: "SSL/SSLv3/TLS 1.0 are deprecated and insecure (Java/JSSE); require TLS 1.3.",
198
+ remediation: 'Use SSLContext.getInstance("TLSv1.3") and prefer PQC-hybrid key exchange.',
199
+ };
200
+ const RULE_JAVA_TLS_NOVERIFY = {
201
+ id: "java-tls-hostname-verification-disabled",
202
+ title: "TLS hostname verification disabled",
203
+ description: "NoopHostnameVerifier / ALLOW_ALL_HOSTNAME_VERIFIER",
204
+ category: "tls",
205
+ severity: "high",
206
+ confidence: "high",
207
+ hndl: false,
208
+ cwe: CWE_CERT_VALIDATION,
209
+ message: "An all-trusting hostname verifier (Java) disables TLS hostname checking (MITM risk).",
210
+ remediation: "Remove the all-trusting verifier; rely on the default hostname verifier.",
211
+ };
212
+ const RULE_JAVA_JWT_ALG = {
213
+ id: "java-jwt-alg",
214
+ title: "Java identifier-form JWT/JOSE algorithm",
215
+ description: "jjwt SignatureAlgorithm.RS/PS/ES* / auth0 Algorithm.RSA*/ECDSA*",
216
+ category: "signature",
217
+ severity: "high",
218
+ confidence: "high",
219
+ algorithm: "unknown",
220
+ hndl: false,
221
+ cwe: CWE_BROKEN_CRYPTO,
222
+ message: "A classical JWT/JOSE signature algorithm (Java, identifier form) is used, forgeable by a quantum attacker.",
223
+ remediation: "ML-DSA-65 (FIPS 204); track IETF PQC JOSE/COSE algorithms",
224
+ };
127
225
  /**
128
226
  * Classify a `<factory>.getInstance("<alg>")` pair into a rule, or null when the
129
227
  * algorithm is not classical asymmetric crypto (AES, HMAC, PBKDF2, hashes, …).
@@ -143,6 +241,12 @@ function classifyGetInstance(factory, rawAlg) {
143
241
  return RULE_JAVA_EDDSA;
144
242
  if (alg.includes("X25519") || alg.includes("X448") || alg === "XDH")
145
243
  return RULE_JAVA_XDH;
244
+ // RSASSA-PSS is an RSA *signature* scheme, not encryption/KEM. The string
245
+ // contains "RSA", so it must be caught here — BEFORE the generic RSA branch
246
+ // below, which would otherwise (mis)classify it as HNDL-exposed RSA
247
+ // encryption (java-rsa / hndl:true). Signatures are hndl:false. (Fixes F8.)
248
+ if (alg.includes("PSS"))
249
+ return RULE_JAVA_RSA_SIGN;
146
250
  if (alg.includes("RSA"))
147
251
  return isSignature ? RULE_JAVA_RSA_SIGN : RULE_JAVA_RSA;
148
252
  if (alg.includes("DSA"))
@@ -161,6 +265,24 @@ const BC_CLASS_RULES = {
161
265
  Ed448Signer: RULE_JAVA_EDDSA,
162
266
  X25519Agreement: RULE_JAVA_XDH,
163
267
  X448Agreement: RULE_JAVA_XDH,
268
+ ECDHBasicAgreement: RULE_JAVA_ECDH,
269
+ DHBasicAgreement: RULE_JAVA_DH,
270
+ X25519KeyPairGenerator: RULE_JAVA_XDH,
271
+ Ed25519KeyPairGenerator: RULE_JAVA_EDDSA,
272
+ RSAEngine: RULE_JAVA_RSA,
273
+ OAEPEncoding: RULE_JAVA_RSA,
274
+ };
275
+ /** BouncyCastle lightweight-API bare-constructor class name → family rule. */
276
+ const BC_CURVE_CLASS_RULES = {
277
+ X448KeyPairGenerator: RULE_JAVA_BC_X448,
278
+ X448Agreement: RULE_JAVA_BC_X448,
279
+ X448PrivateKeyParameters: RULE_JAVA_BC_X448,
280
+ X25519KeyPairGenerator: RULE_JAVA_BC_X25519,
281
+ X25519Agreement: RULE_JAVA_BC_X25519,
282
+ Ed448KeyPairGenerator: RULE_JAVA_BC_EDDSA,
283
+ Ed448Signer: RULE_JAVA_BC_EDDSA,
284
+ Ed25519KeyPairGenerator: RULE_JAVA_BC_EDDSA,
285
+ Ed25519Signer: RULE_JAVA_BC_EDDSA,
164
286
  };
165
287
  /** Detects classical asymmetric crypto in Java / Kotlin (JCA + BouncyCastle). */
166
288
  export const javaDetector = {
@@ -178,6 +300,12 @@ export const javaDetector = {
178
300
  RULE_JAVA_DH,
179
301
  RULE_JAVA_XDH,
180
302
  RULE_JAVA_EDDSA,
303
+ RULE_JAVA_BC_X448,
304
+ RULE_JAVA_BC_X25519,
305
+ RULE_JAVA_BC_EDDSA,
306
+ RULE_JAVA_TLS_LEGACY,
307
+ RULE_JAVA_TLS_NOVERIFY,
308
+ RULE_JAVA_JWT_ALG,
181
309
  ],
182
310
  appliesTo: (f) => hasExtension(f, JAVA_EXTENSIONS),
183
311
  detect({ file, content }) {
@@ -194,6 +322,43 @@ export const javaDetector = {
194
322
  return;
195
323
  findings.push(findingFromRule(rule, { file, content, index: m.index, matchLength: m[0].length }));
196
324
  });
325
+ // BouncyCastle lightweight-API classes as a bare constructor call (Kotlin
326
+ // form, no `new`). RE_JAVA_BC_CURVE's negative lookbehind excludes the
327
+ // `new <Class>(` form already handled above, so this only adds the missed
328
+ // 448/25519 Kotlin-style matches — no double-counting.
329
+ eachMatch(RE_JAVA_BC_CURVE, content, (m) => {
330
+ const rule = BC_CURVE_CLASS_RULES[m[1]];
331
+ if (!rule)
332
+ return;
333
+ findings.push(findingFromRule(rule, { file, content, index: m.index, matchLength: m[0].length }));
334
+ });
335
+ // Legacy SSL/TLS protocol version requested from SSLContext.
336
+ eachMatch(RE_JAVA_TLS_LEGACY, content, (m) => {
337
+ findings.push(findingFromRule(RULE_JAVA_TLS_LEGACY, {
338
+ file,
339
+ content,
340
+ index: m.index,
341
+ matchLength: m[0].length,
342
+ }));
343
+ });
344
+ // All-trusting hostname verifier — disables TLS hostname verification.
345
+ eachMatch(RE_JAVA_TLS_NOVERIFY, content, (m) => {
346
+ findings.push(findingFromRule(RULE_JAVA_TLS_NOVERIFY, {
347
+ file,
348
+ content,
349
+ index: m.index,
350
+ matchLength: m[0].length,
351
+ }));
352
+ });
353
+ // Identifier-form JWT/JOSE signature algorithms (jjwt / auth0).
354
+ eachMatch(RE_JAVA_JWT_ALG, content, (m) => {
355
+ findings.push(findingFromRule(RULE_JAVA_JWT_ALG, {
356
+ file,
357
+ content,
358
+ index: m.index,
359
+ matchLength: m[0].length,
360
+ }));
361
+ });
197
362
  return findings;
198
363
  },
199
364
  };
@@ -1 +1 @@
1
- {"version":3,"file":"java.js","sourceRoot":"","sources":["../../src/detectors/java.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"java.js","sourceRoot":"","sources":["../../src/detectors/java.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Source-code detector for classical, non-quantum-safe asymmetric cryptography\n * in Java / Kotlin (the JCA — Java Cryptography Architecture). Same lexical\n * strategy as the other language packs.\n *\n * The JCA funnels almost everything through a handful of factory methods keyed\n * by an ALGORITHM STRING: `KeyPairGenerator.getInstance(\"RSA\")`,\n * `Signature.getInstance(\"SHA256withECDSA\")`, `Cipher.getInstance(\"RSA/ECB/…\")`,\n * `KeyAgreement.getInstance(\"ECDH\")`. So detection here is two steps: match the\n * `<Factory>.getInstance(\"<alg>\")` call, then classify the (factory, alg) pair\n * into a rule. Symmetric / hashing algorithms (\"AES\", \"HmacSHA256\", …) classify\n * to nothing and are ignored. A small set of BouncyCastle lightweight-API class\n * names (`new ECDSASigner()`, `new X25519Agreement()`, …) is matched directly.\n *\n * HNDL policy mirrors the other detectors: KEM / key agreement (RSA encryption,\n * (EC)DH, X25519/X448) is harvest-now-decrypt-later exposed (hndl:true);\n * signatures (RSA/ECDSA/DSA/EdDSA) are hndl:false but forgeable by a quantum\n * attacker. `KeyPairGenerator.getInstance(\"EC\")` is ambiguous (an EC key feeds\n * both ECDSA and ECDH), so it is classified conservatively as\n * key-exchange-capable (hndl:true), exactly as the Node/Python EC keygen rules.\n */\nimport type { Detector, Finding, RuleMeta } from \"../types.js\";\nimport { JAVA_EXTENSIONS, eachMatch, findingFromRule, hasExtension } from \"../detect-utils.js\";\nimport { CWE_BROKEN_CRYPTO, CWE_CERT_VALIDATION, CWE_WEAK_STRENGTH } from \"../cwe.js\";\n\n/* -------------------------------------------------------------------------- */\n/* Regexes */\n/* -------------------------------------------------------------------------- */\n\n// <Factory>.getInstance(\"<alg>\") — the JCA entry points that carry asymmetric\n// algorithms. KeyGenerator/MessageDigest/Mac are intentionally excluded (they\n// are symmetric / hashing only).\nconst RE_JAVA_GETINSTANCE =\n /\\b(KeyPairGenerator|Signature|Cipher|KeyAgreement|KeyFactory)\\s*\\.\\s*getInstance\\s*\\(\\s*\"([^\"]+)\"/g;\n\n// BouncyCastle lightweight-API class instantiations.\nconst RE_JAVA_BC =\n /\\bnew\\s+(RSAKeyPairGenerator|DSAKeyPairGenerator|ECKeyPairGenerator|ECDSASigner|Ed25519Signer|Ed448Signer|X25519Agreement|X448Agreement|ECDHBasicAgreement|DHBasicAgreement|X25519KeyPairGenerator|Ed25519KeyPairGenerator|RSAEngine|OAEPEncoding)\\s*\\(/g;\n\n// BouncyCastle lightweight-API curve/EdDSA classes as a BARE constructor call —\n// the Kotlin form (`X448KeyPairGenerator()`, no `new` keyword). RE_JAVA_BC above\n// only matches the Java `new <Class>(` form, so Kotlin sources that drive the\n// lightweight API directly are missed. The negative lookbehind `(?<!\\bnew\\s+)`\n// keeps this additive: `new X448Agreement(` stays with RE_JAVA_BC (java-xdh),\n// while bare `X448Agreement(` routes to the family-specific rules below. Scoped\n// to the exact X448/X25519/Ed448/Ed25519 class names to stay precise.\nconst RE_JAVA_BC_CURVE =\n /(?<!\\bnew\\s+)\\b(X448KeyPairGenerator|X448Agreement|X448PrivateKeyParameters|X25519KeyPairGenerator|X25519Agreement|Ed448KeyPairGenerator|Ed448Signer|Ed25519KeyPairGenerator|Ed25519Signer)\\s*\\(/g;\n\n// Insecure JSSE / TLS configuration expressed in Java source. Mirrors the JS\n// tlsDetector in source.ts (category \"tls\"): a legacy SSL/TLS protocol version\n// requested from SSLContext, and TLS hostname verification neutered via an\n// all-trusting verifier (Apache HttpClient's NoopHostnameVerifier /\n// ALLOW_ALL_HOSTNAME_VERIFIER).\nconst RE_JAVA_TLS_LEGACY = /\\bSSLContext\\s*\\.\\s*getInstance\\s*\\(\\s*\"(SSL|SSLv3|TLSv1)\"/g;\nconst RE_JAVA_TLS_NOVERIFY = /\\b(NoopHostnameVerifier|ALLOW_ALL_HOSTNAME_VERIFIER)\\b/g;\n\n// Identifier-form JWT/JOSE signature algorithms (audit F7). The quoted-string\n// alg token (\"RS256\") is caught by the language-agnostic jwt-jose detector, but\n// the Java JWT libraries pass the alg as an IDENTIFIER, not a string literal:\n// jjwt's `SignatureAlgorithm.RS256` and auth0 java-jwt's `Algorithm.RSA256` /\n// `Algorithm.ECDSA256`. (\"SignatureAlgorithm\" has no word boundary before its\n// \"Algorithm\", so the auth0 branch cannot re-match the jjwt form.)\nconst RE_JAVA_JWT_ALG =\n /\\bSignatureAlgorithm\\.(?:RS|PS|ES)(?:256|384|512)\\b|\\bAlgorithm\\.(?:RSA|ECDSA)(?:256|384|512)\\b/g;\n\n/* -------------------------------------------------------------------------- */\n/* Rule catalog */\n/* -------------------------------------------------------------------------- */\n\nconst RULE_JAVA_RSA: RuleMeta = {\n id: \"java-rsa\",\n title: \"Java RSA key/encryption\",\n description: \"JCA RSA KeyPairGenerator / Cipher / KeyFactory\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical RSA (Java/JCA) is not quantum-safe and RSA encryption is HNDL-exposed.\",\n};\nconst RULE_JAVA_RSA_SIGN: RuleMeta = {\n id: \"java-rsa-sign\",\n title: \"Java RSA signature\",\n description: 'JCA Signature.getInstance(\"…withRSA\")',\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical RSA signing (Java/JCA) is forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_JAVA_EC_KEYGEN: RuleMeta = {\n id: \"java-ec-keygen\",\n title: \"Java EC key generation\",\n description: 'JCA KeyPairGenerator.getInstance(\"EC\")',\n category: \"key-exchange\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDH\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Generates a classical EC key pair (Java/JCA). EC keys feed BOTH ECDSA signatures and ECDH key agreement; the ECDH path is harvest-now-decrypt-later exposed.\",\n remediation:\n \"For key agreement: hybrid X25519MLKEM768 (ML-KEM-768). For signatures: ML-DSA-65 (FIPS 204).\",\n};\nconst RULE_JAVA_ECDSA_SIGN: RuleMeta = {\n id: \"java-ecdsa-sign\",\n title: \"Java ECDSA signature\",\n description: 'JCA Signature.getInstance(\"…withECDSA\")',\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical ECDSA signing (Java/JCA) is forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_JAVA_ECDH: RuleMeta = {\n id: \"java-ecdh\",\n title: \"Java ECDH key agreement\",\n description: 'JCA KeyAgreement.getInstance(\"ECDH\")',\n category: \"key-exchange\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDH\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Elliptic-curve Diffie-Hellman (Java/JCA) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_JAVA_DSA: RuleMeta = {\n id: \"java-dsa\",\n title: \"Java DSA key/signature\",\n description: \"JCA DSA KeyPairGenerator / Signature\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"DSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical DSA (Java/JCA) is deprecated and forgeable by a quantum attacker.\",\n remediation: \"Rotate off DSA and migrate to ML-DSA-65 (FIPS 204).\",\n};\nconst RULE_JAVA_DH: RuleMeta = {\n id: \"java-dh\",\n title: \"Java Diffie-Hellman key exchange\",\n description: \"JCA DiffieHellman KeyPairGenerator / KeyAgreement\",\n category: \"key-exchange\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"DH\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Finite-field Diffie-Hellman (Java/JCA) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_JAVA_XDH: RuleMeta = {\n id: \"java-xdh\",\n title: \"Java X25519/X448 key agreement\",\n description: \"JCA XDH / X25519 / X448 (KeyPairGenerator / KeyAgreement)\",\n category: \"key-exchange\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"X25519\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"X25519/X448 (Java/JCA) is modern but still classical key agreement — harvest-now-decrypt-later.\",\n};\nconst RULE_JAVA_EDDSA: RuleMeta = {\n id: \"java-eddsa\",\n title: \"Java Ed25519/Ed448 signature\",\n description: \"JCA EdDSA / Ed25519 / Ed448\",\n category: \"signature\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"EdDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Ed25519/Ed448 (Java/JCA) is a modern but still classical signature scheme.\",\n};\n// BouncyCastle lightweight-API rules for bare (Kotlin-form) constructor calls.\n// Split by family so X448 and X25519 report their own algorithm string (java-xdh\n// lumps both under \"X25519\"). Severity/CWE copied from the JCA siblings above.\nconst RULE_JAVA_BC_X448: RuleMeta = {\n id: \"java-bc-x448\",\n title: \"Java/Kotlin X448 key agreement (BouncyCastle lightweight API)\",\n description: \"BouncyCastle X448KeyPairGenerator / X448Agreement / X448PrivateKeyParameters\",\n category: \"key-exchange\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"X448\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"X448 (Java/Kotlin, BouncyCastle lightweight API) is modern but still classical key agreement — harvest-now-decrypt-later.\",\n};\nconst RULE_JAVA_BC_X25519: RuleMeta = {\n id: \"java-bc-x25519\",\n title: \"Java/Kotlin X25519 key agreement (BouncyCastle lightweight API)\",\n description: \"BouncyCastle X25519KeyPairGenerator / X25519Agreement\",\n category: \"key-exchange\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"X25519\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"X25519 (Java/Kotlin, BouncyCastle lightweight API) is modern but still classical key agreement — harvest-now-decrypt-later.\",\n};\nconst RULE_JAVA_BC_EDDSA: RuleMeta = {\n id: \"java-bc-eddsa\",\n title: \"Java/Kotlin Ed25519/Ed448 signature (BouncyCastle lightweight API)\",\n description:\n \"BouncyCastle Ed448KeyPairGenerator / Ed448Signer / Ed25519KeyPairGenerator / Ed25519Signer\",\n category: \"signature\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"EdDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Ed25519/Ed448 (Java/Kotlin, BouncyCastle lightweight API) is a modern but still classical signature scheme.\",\n};\nconst RULE_JAVA_TLS_LEGACY: RuleMeta = {\n id: \"java-tls-legacy-version\",\n title: \"Legacy SSL/TLS version requested\",\n description: 'SSLContext.getInstance(\"SSL\" | \"SSLv3\" | \"TLSv1\")',\n category: \"tls\",\n severity: \"medium\",\n confidence: \"high\",\n hndl: false,\n cwe: CWE_WEAK_STRENGTH,\n message: \"SSL/SSLv3/TLS 1.0 are deprecated and insecure (Java/JSSE); require TLS 1.3.\",\n remediation: 'Use SSLContext.getInstance(\"TLSv1.3\") and prefer PQC-hybrid key exchange.',\n};\nconst RULE_JAVA_TLS_NOVERIFY: RuleMeta = {\n id: \"java-tls-hostname-verification-disabled\",\n title: \"TLS hostname verification disabled\",\n description: \"NoopHostnameVerifier / ALLOW_ALL_HOSTNAME_VERIFIER\",\n category: \"tls\",\n severity: \"high\",\n confidence: \"high\",\n hndl: false,\n cwe: CWE_CERT_VALIDATION,\n message: \"An all-trusting hostname verifier (Java) disables TLS hostname checking (MITM risk).\",\n remediation: \"Remove the all-trusting verifier; rely on the default hostname verifier.\",\n};\nconst RULE_JAVA_JWT_ALG: RuleMeta = {\n id: \"java-jwt-alg\",\n title: \"Java identifier-form JWT/JOSE algorithm\",\n description: \"jjwt SignatureAlgorithm.RS/PS/ES* / auth0 Algorithm.RSA*/ECDSA*\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"unknown\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"A classical JWT/JOSE signature algorithm (Java, identifier form) is used, forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204); track IETF PQC JOSE/COSE algorithms\",\n};\n\n/**\n * Classify a `<factory>.getInstance(\"<alg>\")` pair into a rule, or null when the\n * algorithm is not classical asymmetric crypto (AES, HMAC, PBKDF2, hashes, …).\n * `alg` is normalised to upper-case with any Cipher transformation suffix\n * (`RSA/ECB/OAEPPadding` → `RSA`) stripped.\n */\nfunction classifyGetInstance(factory: string, rawAlg: string): RuleMeta | null {\n const alg = rawAlg.split(\"/\")[0].trim().toUpperCase();\n const isSignature = factory === \"Signature\";\n\n if (alg.includes(\"ECDSA\")) return RULE_JAVA_ECDSA_SIGN;\n if (alg.includes(\"ECDH\")) return RULE_JAVA_ECDH;\n if (alg === \"EC\") return isSignature ? RULE_JAVA_ECDSA_SIGN : RULE_JAVA_EC_KEYGEN;\n if (alg.includes(\"ED25519\") || alg.includes(\"ED448\") || alg.includes(\"EDDSA\"))\n return RULE_JAVA_EDDSA;\n if (alg.includes(\"X25519\") || alg.includes(\"X448\") || alg === \"XDH\") return RULE_JAVA_XDH;\n // RSASSA-PSS is an RSA *signature* scheme, not encryption/KEM. The string\n // contains \"RSA\", so it must be caught here — BEFORE the generic RSA branch\n // below, which would otherwise (mis)classify it as HNDL-exposed RSA\n // encryption (java-rsa / hndl:true). Signatures are hndl:false. (Fixes F8.)\n if (alg.includes(\"PSS\")) return RULE_JAVA_RSA_SIGN;\n if (alg.includes(\"RSA\")) return isSignature ? RULE_JAVA_RSA_SIGN : RULE_JAVA_RSA;\n if (alg.includes(\"DSA\")) return RULE_JAVA_DSA; // ECDSA already handled above\n if (alg.includes(\"DH\") || alg.includes(\"DIFFIEHELLMAN\")) return RULE_JAVA_DH;\n return null;\n}\n\n/** BouncyCastle lightweight-API class name → rule. */\nconst BC_CLASS_RULES: Record<string, RuleMeta> = {\n RSAKeyPairGenerator: RULE_JAVA_RSA,\n DSAKeyPairGenerator: RULE_JAVA_DSA,\n ECKeyPairGenerator: RULE_JAVA_EC_KEYGEN,\n ECDSASigner: RULE_JAVA_ECDSA_SIGN,\n Ed25519Signer: RULE_JAVA_EDDSA,\n Ed448Signer: RULE_JAVA_EDDSA,\n X25519Agreement: RULE_JAVA_XDH,\n X448Agreement: RULE_JAVA_XDH,\n ECDHBasicAgreement: RULE_JAVA_ECDH,\n DHBasicAgreement: RULE_JAVA_DH,\n X25519KeyPairGenerator: RULE_JAVA_XDH,\n Ed25519KeyPairGenerator: RULE_JAVA_EDDSA,\n RSAEngine: RULE_JAVA_RSA,\n OAEPEncoding: RULE_JAVA_RSA,\n};\n\n/** BouncyCastle lightweight-API bare-constructor class name → family rule. */\nconst BC_CURVE_CLASS_RULES: Record<string, RuleMeta> = {\n X448KeyPairGenerator: RULE_JAVA_BC_X448,\n X448Agreement: RULE_JAVA_BC_X448,\n X448PrivateKeyParameters: RULE_JAVA_BC_X448,\n X25519KeyPairGenerator: RULE_JAVA_BC_X25519,\n X25519Agreement: RULE_JAVA_BC_X25519,\n Ed448KeyPairGenerator: RULE_JAVA_BC_EDDSA,\n Ed448Signer: RULE_JAVA_BC_EDDSA,\n Ed25519KeyPairGenerator: RULE_JAVA_BC_EDDSA,\n Ed25519Signer: RULE_JAVA_BC_EDDSA,\n};\n\n/** Detects classical asymmetric crypto in Java / Kotlin (JCA + BouncyCastle). */\nexport const javaDetector: Detector = {\n id: \"java-crypto\",\n description: \"Classical asymmetric crypto in Java/Kotlin (JCA getInstance + BouncyCastle)\",\n scope: \"source\",\n language: \"java\",\n rules: [\n RULE_JAVA_RSA,\n RULE_JAVA_RSA_SIGN,\n RULE_JAVA_EC_KEYGEN,\n RULE_JAVA_ECDSA_SIGN,\n RULE_JAVA_ECDH,\n RULE_JAVA_DSA,\n RULE_JAVA_DH,\n RULE_JAVA_XDH,\n RULE_JAVA_EDDSA,\n RULE_JAVA_BC_X448,\n RULE_JAVA_BC_X25519,\n RULE_JAVA_BC_EDDSA,\n RULE_JAVA_TLS_LEGACY,\n RULE_JAVA_TLS_NOVERIFY,\n RULE_JAVA_JWT_ALG,\n ],\n appliesTo: (f) => hasExtension(f, JAVA_EXTENSIONS),\n detect({ file, content }): Finding[] {\n const findings: Finding[] = [];\n\n eachMatch(RE_JAVA_GETINSTANCE, content, (m) => {\n const rule = classifyGetInstance(m[1], m[2]);\n if (!rule) return; // symmetric / hashing algorithm — not our concern.\n findings.push(\n findingFromRule(rule, { file, content, index: m.index, matchLength: m[0].length }),\n );\n });\n\n eachMatch(RE_JAVA_BC, content, (m) => {\n const rule = BC_CLASS_RULES[m[1]];\n if (!rule) return;\n findings.push(\n findingFromRule(rule, { file, content, index: m.index, matchLength: m[0].length }),\n );\n });\n\n // BouncyCastle lightweight-API classes as a bare constructor call (Kotlin\n // form, no `new`). RE_JAVA_BC_CURVE's negative lookbehind excludes the\n // `new <Class>(` form already handled above, so this only adds the missed\n // 448/25519 Kotlin-style matches — no double-counting.\n eachMatch(RE_JAVA_BC_CURVE, content, (m) => {\n const rule = BC_CURVE_CLASS_RULES[m[1]];\n if (!rule) return;\n findings.push(\n findingFromRule(rule, { file, content, index: m.index, matchLength: m[0].length }),\n );\n });\n\n // Legacy SSL/TLS protocol version requested from SSLContext.\n eachMatch(RE_JAVA_TLS_LEGACY, content, (m) => {\n findings.push(\n findingFromRule(RULE_JAVA_TLS_LEGACY, {\n file,\n content,\n index: m.index,\n matchLength: m[0].length,\n }),\n );\n });\n\n // All-trusting hostname verifier — disables TLS hostname verification.\n eachMatch(RE_JAVA_TLS_NOVERIFY, content, (m) => {\n findings.push(\n findingFromRule(RULE_JAVA_TLS_NOVERIFY, {\n file,\n content,\n index: m.index,\n matchLength: m[0].length,\n }),\n );\n });\n\n // Identifier-form JWT/JOSE signature algorithms (jjwt / auth0).\n eachMatch(RE_JAVA_JWT_ALG, content, (m) => {\n findings.push(\n findingFromRule(RULE_JAVA_JWT_ALG, {\n file,\n content,\n index: m.index,\n matchLength: m[0].length,\n }),\n );\n });\n\n return findings;\n },\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"pem.d.ts","sourceRoot":"","sources":["../../src/detectors/pem.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;AAwJ/D,+DAA+D;AAC/D,eAAO,MAAM,WAAW,EAAE,QA2BzB,CAAC"}
1
+ {"version":3,"file":"pem.d.ts","sourceRoot":"","sources":["../../src/detectors/pem.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;AA4M/D,+DAA+D;AAC/D,eAAO,MAAM,WAAW,EAAE,QA2BzB,CAAC"}
@@ -66,7 +66,7 @@ const PEM_RULES = [
66
66
  cwe: CWE_HARDCODED_KEY,
67
67
  sensitive: true,
68
68
  message: "Embedded OpenSSH private key (RSA/ECDSA/Ed25519); classical and not quantum-safe.",
69
- remediation: "Rotate the key; plan migration to PQC-capable SSH (e.g. sntrup761x25519).",
69
+ remediation: "Rotate the key; plan migration to PQC-capable SSH (prefer the mlkem768x25519-sha256 KEX, OpenSSH 10's default since Apr 2025).",
70
70
  },
71
71
  },
72
72
  {
@@ -135,6 +135,54 @@ const PEM_RULES = [
135
135
  remediation: "Plan re-issuance with PQC-capable CAs as ML-DSA certificate profiles mature.",
136
136
  },
137
137
  },
138
+ {
139
+ re: /-----BEGIN (?:RSA )?PUBLIC KEY-----/g,
140
+ meta: {
141
+ id: "pem-public-key",
142
+ title: "Classical public key (PEM)",
143
+ description: "SubjectPublicKeyInfo / PKCS#1 RSA public key block",
144
+ category: "certificate",
145
+ severity: "low",
146
+ confidence: "high",
147
+ algorithm: "unknown",
148
+ hndl: false,
149
+ cwe: CWE_BROKEN_CRYPTO,
150
+ message: "Embedded classical public key (RSA/EC/DSA); its key pair is not quantum-safe — forgeable signatures or classical key exchange.",
151
+ remediation: "Re-issue with PQC keys (ML-DSA / ML-KEM) as the ecosystem adopts them.",
152
+ },
153
+ },
154
+ {
155
+ re: /-----BEGIN DH PARAMETERS-----/g,
156
+ meta: {
157
+ id: "pem-dh-parameters",
158
+ title: "Diffie-Hellman parameters (PEM)",
159
+ description: "Finite-field DH group parameters block",
160
+ category: "key-exchange",
161
+ severity: "medium",
162
+ confidence: "high",
163
+ algorithm: "DH",
164
+ hndl: true,
165
+ cwe: CWE_BROKEN_CRYPTO,
166
+ message: "Embedded finite-field Diffie-Hellman parameters; classical DH key exchange is harvest-now-decrypt-later exposed.",
167
+ remediation: "Migrate key exchange to hybrid X25519MLKEM768 (ML-KEM-768).",
168
+ },
169
+ },
170
+ {
171
+ re: /-----BEGIN (?:NEW )?CERTIFICATE REQUEST-----/g,
172
+ meta: {
173
+ id: "pem-cert-request",
174
+ title: "Certificate signing request (PEM)",
175
+ description: "PKCS#10 certificate request block",
176
+ category: "certificate",
177
+ severity: "low",
178
+ confidence: "high",
179
+ algorithm: "unknown",
180
+ hndl: false,
181
+ cwe: CWE_BROKEN_CRYPTO,
182
+ message: "Embedded PKCS#10 CSR; carries a classical public key and will be signed with classical crypto.",
183
+ remediation: "Re-generate with PQC keys as PQC-capable CAs mature.",
184
+ },
185
+ },
138
186
  ];
139
187
  /** Detects PEM key/certificate material in arbitrary files. */
140
188
  export const pemDetector = {
@@ -1 +1 @@
1
- {"version":3,"file":"pem.js","sourceRoot":"","sources":["../../src/detectors/pem.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pem.js","sourceRoot":"","sources":["../../src/detectors/pem.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Config / certificate detector: finds PEM-encoded cryptographic material in\n * any text file (source, config, .pem, .key, .crt, .env, …). This catches\n * embedded private keys and X.509 certificates regardless of language.\n *\n * Every rule's metadata lives in the {@link RuleMeta} declaration below (the\n * catalog entry); `detect()` builds findings straight from it via\n * `findingFromRule`. All PEM findings are high-confidence exact-marker matches.\n */\nimport type { Detector, Finding, RuleMeta } from \"../types.js\";\nimport { eachMatch, findingFromRule } from \"../detect-utils.js\";\nimport { CWE_BROKEN_CRYPTO, CWE_HARDCODED_KEY } from \"../cwe.js\";\n\n/** A PEM rule: its catalog metadata plus the begin-marker regex that triggers it. */\ninterface PemRule {\n /** Regex matching the PEM begin marker. */\n re: RegExp;\n meta: RuleMeta;\n}\n\nconst PEM_RULES: PemRule[] = [\n {\n re: /-----BEGIN RSA PRIVATE KEY-----/g,\n meta: {\n id: \"pem-rsa-private-key\",\n title: \"RSA private key (PEM)\",\n description: \"PKCS#1 RSA private key block\",\n category: \"certificate\",\n severity: \"critical\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_HARDCODED_KEY,\n sensitive: true,\n message: \"Embedded RSA private key (PKCS#1 PEM); classical and not quantum-safe.\",\n remediation: \"Migrate to ML-DSA / ML-KEM keys and remove embedded private keys from source.\",\n },\n },\n {\n re: /-----BEGIN EC PRIVATE KEY-----/g,\n meta: {\n id: \"pem-ec-private-key\",\n title: \"EC private key (PEM)\",\n description: \"SEC1 EC private key block\",\n category: \"certificate\",\n severity: \"critical\",\n confidence: \"high\",\n algorithm: \"ECDSA\",\n hndl: true,\n cwe: CWE_HARDCODED_KEY,\n sensitive: true,\n message: \"Embedded EC private key (SEC1 PEM); classical ECDSA/ECDH key, not quantum-safe.\",\n remediation:\n \"Migrate to ML-DSA (FIPS 204) keys and remove embedded private keys from source.\",\n },\n },\n {\n re: /-----BEGIN DSA PRIVATE KEY-----/g,\n meta: {\n id: \"pem-dsa-private-key\",\n title: \"DSA private key (PEM)\",\n description: \"DSA private key block\",\n category: \"certificate\",\n severity: \"critical\",\n confidence: \"high\",\n algorithm: \"DSA\",\n hndl: false,\n cwe: CWE_HARDCODED_KEY,\n sensitive: true,\n message:\n \"Embedded DSA private key (PEM); classical, already deprecated, and not quantum-safe.\",\n remediation: \"Rotate immediately (DSA is deprecated) and migrate to ML-DSA-65 (FIPS 204).\",\n },\n },\n {\n re: /-----BEGIN OPENSSH PRIVATE KEY-----/g,\n meta: {\n id: \"pem-openssh-private-key\",\n title: \"OpenSSH private key\",\n description: \"OpenSSH private key block\",\n category: \"certificate\",\n severity: \"critical\",\n confidence: \"high\",\n algorithm: \"unknown\",\n hndl: true,\n cwe: CWE_HARDCODED_KEY,\n sensitive: true,\n message: \"Embedded OpenSSH private key (RSA/ECDSA/Ed25519); classical and not quantum-safe.\",\n remediation:\n \"Rotate the key; plan migration to PQC-capable SSH (prefer the mlkem768x25519-sha256 KEX, OpenSSH 10's default since Apr 2025).\",\n },\n },\n {\n re: /-----BEGIN PGP PRIVATE KEY BLOCK-----/g,\n meta: {\n id: \"pem-pgp-private-key\",\n title: \"PGP/GPG private key block\",\n description: \"OpenPGP private key block\",\n category: \"certificate\",\n severity: \"critical\",\n confidence: \"high\",\n algorithm: \"unknown\",\n hndl: true,\n cwe: CWE_HARDCODED_KEY,\n sensitive: true,\n message:\n \"Embedded PGP/GPG private key block (RSA/ECDSA/EdDSA/ElGamal); classical and not quantum-safe.\",\n remediation: \"Rotate the key; track OpenPGP PQC drafts for migration.\",\n },\n },\n {\n re: /-----BEGIN PGP MESSAGE-----/g,\n meta: {\n id: \"pem-pgp-message\",\n title: \"PGP/GPG encrypted message\",\n description: \"OpenPGP encrypted message block\",\n category: \"certificate\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"unknown\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Embedded PGP/GPG message; likely encrypted with classical RSA/ElGamal (harvest-now-decrypt-later).\",\n remediation: \"Re-encrypt with PQC-capable tooling as OpenPGP PQC profiles mature.\",\n },\n },\n {\n re: /-----BEGIN (?:ENCRYPTED )?PRIVATE KEY-----/g,\n meta: {\n id: \"pem-pkcs8-private-key\",\n title: \"Private key (PKCS#8 PEM)\",\n description: \"PKCS#8 private key block\",\n category: \"certificate\",\n severity: \"critical\",\n confidence: \"high\",\n algorithm: \"unknown\",\n hndl: true,\n cwe: CWE_HARDCODED_KEY,\n sensitive: true,\n message: \"Embedded PKCS#8 private key; likely classical RSA/EC, not quantum-safe.\",\n remediation: \"Migrate to PQC keys and remove embedded private keys from source.\",\n },\n },\n {\n re: /-----BEGIN CERTIFICATE-----/g,\n meta: {\n id: \"pem-certificate\",\n title: \"X.509 certificate (PEM)\",\n description: \"X.509 certificate block\",\n category: \"certificate\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"unknown\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Embedded X.509 certificate; almost certainly signed with classical RSA/ECDSA.\",\n remediation: \"Plan re-issuance with PQC-capable CAs as ML-DSA certificate profiles mature.\",\n },\n },\n {\n re: /-----BEGIN (?:RSA )?PUBLIC KEY-----/g,\n meta: {\n id: \"pem-public-key\",\n title: \"Classical public key (PEM)\",\n description: \"SubjectPublicKeyInfo / PKCS#1 RSA public key block\",\n category: \"certificate\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"unknown\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Embedded classical public key (RSA/EC/DSA); its key pair is not quantum-safe — forgeable signatures or classical key exchange.\",\n remediation: \"Re-issue with PQC keys (ML-DSA / ML-KEM) as the ecosystem adopts them.\",\n },\n },\n {\n re: /-----BEGIN DH PARAMETERS-----/g,\n meta: {\n id: \"pem-dh-parameters\",\n title: \"Diffie-Hellman parameters (PEM)\",\n description: \"Finite-field DH group parameters block\",\n category: \"key-exchange\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"DH\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Embedded finite-field Diffie-Hellman parameters; classical DH key exchange is harvest-now-decrypt-later exposed.\",\n remediation: \"Migrate key exchange to hybrid X25519MLKEM768 (ML-KEM-768).\",\n },\n },\n {\n re: /-----BEGIN (?:NEW )?CERTIFICATE REQUEST-----/g,\n meta: {\n id: \"pem-cert-request\",\n title: \"Certificate signing request (PEM)\",\n description: \"PKCS#10 certificate request block\",\n category: \"certificate\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"unknown\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Embedded PKCS#10 CSR; carries a classical public key and will be signed with classical crypto.\",\n remediation: \"Re-generate with PQC keys as PQC-capable CAs mature.\",\n },\n },\n];\n\n/** Detects PEM key/certificate material in arbitrary files. */\nexport const pemDetector: Detector = {\n id: \"pem-material\",\n description: \"PEM-encoded private keys and X.509 certificates in any file\",\n scope: \"config\",\n language: \"any\",\n rules: PEM_RULES.map((r) => r.meta),\n // Applies to every text file; the walker already filters out binaries.\n appliesTo: () => true,\n detect({ file, content }): Finding[] {\n // Fast reject: only proceed if a PEM header is present at all.\n if (!content.includes(\"-----BEGIN \")) return [];\n\n const findings: Finding[] = [];\n for (const rule of PEM_RULES) {\n eachMatch(rule.re, content, (m) => {\n findings.push(\n findingFromRule(rule.meta, {\n file,\n content,\n index: m.index,\n matchLength: m[0].length,\n }),\n );\n });\n }\n return findings;\n },\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"python.d.ts","sourceRoot":"","sources":["../../src/detectors/python.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;AAsJ/D,4DAA4D;AAC5D,eAAO,MAAM,cAAc,EAAE,QAsC5B,CAAC"}
1
+ {"version":3,"file":"python.d.ts","sourceRoot":"","sources":["../../src/detectors/python.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;AA6N/D,4DAA4D;AAC5D,eAAO,MAAM,cAAc,EAAE,QA8C5B,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { PYTHON_EXTENSIONS, eachMatch, findingFromRule, hasExtension } from "../detect-utils.js";
2
- import { CWE_BROKEN_CRYPTO } from "../cwe.js";
2
+ import { CWE_BROKEN_CRYPTO, CWE_CERT_VALIDATION, CWE_WEAK_STRENGTH } from "../cwe.js";
3
3
  /* -------------------------------------------------------------------------- */
4
4
  /* Precompiled regexes (module scope) */
5
5
  /* -------------------------------------------------------------------------- */
@@ -12,8 +12,15 @@ const RE_PY_RSA_ENCRYPT = /\bpadding\.OAEP\s*\(|\bPKCS1_OAEP\.new\s*\(/g;
12
12
  const RE_PY_EC_KEYGEN = /\bec\.generate_private_key\s*\(|\bECC\.generate\s*\(/g;
13
13
  // ECDSA signatures: cryptography `ec.ECDSA(`, paramiko ECDSAKey.
14
14
  const RE_PY_ECDSA = /\bec\.ECDSA\s*\(|\bparamiko\.ECDSAKey\b|\bECDSAKey\.generate\s*\(/g;
15
+ // ECDH key agreement: cryptography `ec.ECDH(` — the actual harvest-now event in
16
+ // `private_key.exchange(ec.ECDH(), peer)`; previously missed entirely (audit F3).
17
+ const RE_PY_ECDH = /\bec\.ECDH\s*\(/g;
15
18
  // DSA: PyCryptodome `DSA.generate(`, paramiko DSSKey.
16
19
  const RE_PY_DSA = /\bDSA\.generate\s*\(|\bparamiko\.DSSKey\b|\bDSSKey\.generate\s*\(/g;
20
+ // hazmat DSA: cryptography `dsa.generate_private_key(` — the `cryptography` DSA
21
+ // keygen path (lowercase module) that RE_PY_DSA's uppercase `DSA.generate` misses
22
+ // (audit F9-python).
23
+ const RE_PY_HAZMAT_DSA = /\bdsa\.generate_private_key\s*\(/g;
17
24
  // Finite-field Diffie-Hellman (cryptography `dh`).
18
25
  const RE_PY_DH = /\bdh\.generate_parameters\s*\(|\bdh\.DHParameterNumbers\s*\(/g;
19
26
  // Modern-but-classical curve primitives (cryptography). `.generate(` anchors so
@@ -21,6 +28,13 @@ const RE_PY_DH = /\bdh\.generate_parameters\s*\(|\bdh\.DHParameterNumbers\s*\(/g
21
28
  const RE_PY_X25519 = /\bX25519PrivateKey\.generate\s*\(/g;
22
29
  const RE_PY_X448 = /\bX448PrivateKey\.generate\s*\(/g;
23
30
  const RE_PY_EDDSA = /\b(?:Ed25519|Ed448)PrivateKey\.generate\s*\(|\bparamiko\.Ed25519Key\b/g;
31
+ // Python TLS misconfiguration. Mirrors the JS `tlsDetector` split of source.ts:
32
+ // certificate-verification bypass (requests `verify=False`, `ssl.CERT_NONE`,
33
+ // `check_hostname=False`, `ssl._create_unverified_context(`) is the high-severity
34
+ // MITM surface (CWE-295); a pinned legacy protocol (`ssl.PROTOCOL_TLSv1`) is the
35
+ // medium-severity weak-strength surface (CWE-326).
36
+ const RE_PY_TLS_REJECT = /\bverify\s*=\s*False\b|\bssl\.CERT_NONE\b|\bcheck_hostname\s*=\s*False\b|\bssl\._create_unverified_context\s*\(/g;
37
+ const RE_PY_TLS_LEGACY = /\bPROTOCOL_TLSv1\b/g;
24
38
  /* -------------------------------------------------------------------------- */
25
39
  /* Rule catalog */
26
40
  /* -------------------------------------------------------------------------- */
@@ -74,6 +88,18 @@ const RULE_PY_ECDSA = {
74
88
  message: "Classical ECDSA signing (Python) is forgeable by a quantum attacker.",
75
89
  remediation: "ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)",
76
90
  };
91
+ const RULE_PY_ECDH = {
92
+ id: "python-ecdh",
93
+ title: "Python ECDH key agreement",
94
+ description: "cryptography ec.ECDH() exchange",
95
+ category: "key-exchange",
96
+ severity: "high",
97
+ confidence: "high",
98
+ algorithm: "ECDH",
99
+ hndl: true,
100
+ cwe: CWE_BROKEN_CRYPTO,
101
+ message: "Elliptic-curve Diffie-Hellman key agreement (Python) is broken by Shor's algorithm (harvest-now-decrypt-later).",
102
+ };
77
103
  const RULE_PY_DSA = {
78
104
  id: "python-dsa",
79
105
  title: "Python DSA key/usage",
@@ -87,6 +113,19 @@ const RULE_PY_DSA = {
87
113
  message: "Classical DSA (Python) is deprecated and forgeable by a quantum attacker.",
88
114
  remediation: "Rotate off DSA and migrate to ML-DSA-65 (FIPS 204).",
89
115
  };
116
+ const RULE_PY_HAZMAT_DSA = {
117
+ id: "python-hazmat-dsa",
118
+ title: "Python DSA key generation (cryptography)",
119
+ description: "cryptography dsa.generate_private_key",
120
+ category: "signature",
121
+ severity: "high",
122
+ confidence: "high",
123
+ algorithm: "DSA",
124
+ hndl: false,
125
+ cwe: CWE_BROKEN_CRYPTO,
126
+ message: "cryptography dsa.generate_private_key (Python) creates a classical DSA key; DSA is deprecated and forgeable by a quantum attacker.",
127
+ remediation: "Rotate off DSA and migrate to ML-DSA-65 (FIPS 204).",
128
+ };
90
129
  const RULE_PY_DH = {
91
130
  id: "python-dh",
92
131
  title: "Python Diffie-Hellman key exchange",
@@ -104,7 +143,7 @@ const RULE_PY_X25519 = {
104
143
  title: "Python X25519 key exchange",
105
144
  description: "cryptography X25519PrivateKey.generate",
106
145
  category: "key-exchange",
107
- severity: "low",
146
+ severity: "medium",
108
147
  confidence: "high",
109
148
  algorithm: "X25519",
110
149
  hndl: true,
@@ -116,7 +155,7 @@ const RULE_PY_X448 = {
116
155
  title: "Python X448 key exchange",
117
156
  description: "cryptography X448PrivateKey.generate",
118
157
  category: "key-exchange",
119
- severity: "low",
158
+ severity: "medium",
120
159
  confidence: "high",
121
160
  algorithm: "X448",
122
161
  hndl: true,
@@ -135,6 +174,30 @@ const RULE_PY_EDDSA = {
135
174
  cwe: CWE_BROKEN_CRYPTO,
136
175
  message: "Ed25519/Ed448 (Python) is a modern but still classical signature scheme.",
137
176
  };
177
+ const RULE_PY_TLS_REJECT = {
178
+ id: "python-tls-reject",
179
+ title: "Python TLS certificate verification disabled",
180
+ description: "requests verify=False / ssl.CERT_NONE / check_hostname=False / _create_unverified_context",
181
+ category: "tls",
182
+ severity: "high",
183
+ confidence: "high",
184
+ hndl: false,
185
+ cwe: CWE_CERT_VALIDATION,
186
+ message: "TLS certificate verification is disabled (verify=False / CERT_NONE / check_hostname=False / _create_unverified_context), which allows man-in-the-middle attacks.",
187
+ remediation: "Enable certificate verification (verify=True, ssl.CERT_REQUIRED, check_hostname=True) and verify certificates properly.",
188
+ };
189
+ const RULE_PY_TLS_LEGACY = {
190
+ id: "python-tls-legacy-version",
191
+ title: "Python legacy TLS version pinned",
192
+ description: "ssl.PROTOCOL_TLSv1 (TLS 1.0)",
193
+ category: "tls",
194
+ severity: "medium",
195
+ confidence: "high",
196
+ hndl: false,
197
+ cwe: CWE_WEAK_STRENGTH,
198
+ message: "TLS 1.0 (ssl.PROTOCOL_TLSv1) is deprecated and insecure; require TLS 1.3.",
199
+ remediation: "Use ssl.PROTOCOL_TLS_CLIENT with minimum_version = ssl.TLSVersion.TLSv1_3 and prefer PQC-hybrid key exchange.",
200
+ };
138
201
  /** Detects classical asymmetric crypto in Python source. */
139
202
  export const pythonDetector = {
140
203
  id: "python-crypto",
@@ -146,11 +209,15 @@ export const pythonDetector = {
146
209
  RULE_PY_RSA_ENCRYPT,
147
210
  RULE_PY_EC_KEYGEN,
148
211
  RULE_PY_ECDSA,
212
+ RULE_PY_ECDH,
149
213
  RULE_PY_DSA,
214
+ RULE_PY_HAZMAT_DSA,
150
215
  RULE_PY_DH,
151
216
  RULE_PY_X25519,
152
217
  RULE_PY_X448,
153
218
  RULE_PY_EDDSA,
219
+ RULE_PY_TLS_REJECT,
220
+ RULE_PY_TLS_LEGACY,
154
221
  ],
155
222
  appliesTo: (f) => hasExtension(f, PYTHON_EXTENSIONS),
156
223
  detect({ file, content }) {
@@ -160,11 +227,15 @@ export const pythonDetector = {
160
227
  add(RE_PY_RSA_ENCRYPT, RULE_PY_RSA_ENCRYPT);
161
228
  add(RE_PY_EC_KEYGEN, RULE_PY_EC_KEYGEN);
162
229
  add(RE_PY_ECDSA, RULE_PY_ECDSA);
230
+ add(RE_PY_ECDH, RULE_PY_ECDH);
163
231
  add(RE_PY_DSA, RULE_PY_DSA);
232
+ add(RE_PY_HAZMAT_DSA, RULE_PY_HAZMAT_DSA);
164
233
  add(RE_PY_DH, RULE_PY_DH);
165
234
  add(RE_PY_X25519, RULE_PY_X25519);
166
235
  add(RE_PY_X448, RULE_PY_X448);
167
236
  add(RE_PY_EDDSA, RULE_PY_EDDSA);
237
+ add(RE_PY_TLS_REJECT, RULE_PY_TLS_REJECT);
238
+ add(RE_PY_TLS_LEGACY, RULE_PY_TLS_LEGACY);
168
239
  return findings;
169
240
  },
170
241
  };
@@ -1 +1 @@
1
- {"version":3,"file":"python.js","sourceRoot":"","sources":["../../src/detectors/python.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACjG,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF,6EAA6E;AAC7E,oEAAoE;AACpE,MAAM,gBAAgB,GACpB,qGAAqG,CAAC;AACxG,wEAAwE;AACxE,MAAM,iBAAiB,GAAG,8CAA8C,CAAC;AACzE,yEAAyE;AACzE,MAAM,eAAe,GAAG,uDAAuD,CAAC;AAChF,iEAAiE;AACjE,MAAM,WAAW,GAAG,oEAAoE,CAAC;AACzF,sDAAsD;AACtD,MAAM,SAAS,GAAG,oEAAoE,CAAC;AACvF,mDAAmD;AACnD,MAAM,QAAQ,GAAG,+DAA+D,CAAC;AACjF,gFAAgF;AAChF,iDAAiD;AACjD,MAAM,YAAY,GAAG,oCAAoC,CAAC;AAC1D,MAAM,UAAU,GAAG,kCAAkC,CAAC;AACtD,MAAM,WAAW,GAAG,wEAAwE,CAAC;AAE7F,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF,MAAM,kBAAkB,GAAa;IACnC,EAAE,EAAE,mBAAmB;IACvB,KAAK,EAAE,2BAA2B;IAClC,WAAW,EACT,qFAAqF;IACvF,QAAQ,EAAE,KAAK;IACf,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,KAAK;IAChB,IAAI,EAAE,IAAI;IACV,GAAG,EAAE,iBAAiB;IACtB,OAAO,EAAE,yEAAyE;CACnF,CAAC;AACF,MAAM,mBAAmB,GAAa;IACpC,EAAE,EAAE,oBAAoB;IACxB,KAAK,EAAE,kCAAkC;IACzC,WAAW,EAAE,0CAA0C;IACvD,QAAQ,EAAE,KAAK;IACf,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,KAAK;IAChB,IAAI,EAAE,IAAI;IACV,GAAG,EAAE,iBAAiB;IACtB,OAAO,EACL,0GAA0G;CAC7G,CAAC;AACF,MAAM,iBAAiB,GAAa;IAClC,EAAE,EAAE,kBAAkB;IACtB,KAAK,EAAE,0BAA0B;IACjC,WAAW,EAAE,kEAAkE;IAC/E,QAAQ,EAAE,cAAc;IACxB,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,MAAM;IACjB,IAAI,EAAE,IAAI;IACV,GAAG,EAAE,iBAAiB;IACtB,OAAO,EACL,4JAA4J;IAC9J,WAAW,EACT,8FAA8F;CACjG,CAAC;AACF,MAAM,aAAa,GAAa;IAC9B,EAAE,EAAE,cAAc;IAClB,KAAK,EAAE,wBAAwB;IAC/B,WAAW,EAAE,2CAA2C;IACxD,QAAQ,EAAE,WAAW;IACrB,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,OAAO;IAClB,IAAI,EAAE,KAAK;IACX,GAAG,EAAE,iBAAiB;IACtB,OAAO,EAAE,sEAAsE;IAC/E,WAAW,EAAE,4CAA4C;CAC1D,CAAC;AACF,MAAM,WAAW,GAAa;IAC5B,EAAE,EAAE,YAAY;IAChB,KAAK,EAAE,sBAAsB;IAC7B,WAAW,EAAE,6CAA6C;IAC1D,QAAQ,EAAE,WAAW;IACrB,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,KAAK;IAChB,IAAI,EAAE,KAAK;IACX,GAAG,EAAE,iBAAiB;IACtB,OAAO,EAAE,2EAA2E;IACpF,WAAW,EAAE,qDAAqD;CACnE,CAAC;AACF,MAAM,UAAU,GAAa;IAC3B,EAAE,EAAE,WAAW;IACf,KAAK,EAAE,oCAAoC;IAC3C,WAAW,EAAE,0DAA0D;IACvE,QAAQ,EAAE,cAAc;IACxB,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,IAAI;IACf,IAAI,EAAE,IAAI;IACV,GAAG,EAAE,iBAAiB;IACtB,OAAO,EACL,iGAAiG;CACpG,CAAC;AACF,MAAM,cAAc,GAAa;IAC/B,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,4BAA4B;IACnC,WAAW,EAAE,wCAAwC;IACrD,QAAQ,EAAE,cAAc;IACxB,QAAQ,EAAE,KAAK;IACf,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,QAAQ;IACnB,IAAI,EAAE,IAAI;IACV,GAAG,EAAE,iBAAiB;IACtB,OAAO,EACL,0FAA0F;CAC7F,CAAC;AACF,MAAM,YAAY,GAAa;IAC7B,EAAE,EAAE,aAAa;IACjB,KAAK,EAAE,0BAA0B;IACjC,WAAW,EAAE,sCAAsC;IACnD,QAAQ,EAAE,cAAc;IACxB,QAAQ,EAAE,KAAK;IACf,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,MAAM;IACjB,IAAI,EAAE,IAAI;IACV,GAAG,EAAE,iBAAiB;IACtB,OAAO,EAAE,wFAAwF;CAClG,CAAC;AACF,MAAM,aAAa,GAAa;IAC9B,EAAE,EAAE,cAAc;IAClB,KAAK,EAAE,gCAAgC;IACvC,WAAW,EAAE,sEAAsE;IACnF,QAAQ,EAAE,WAAW;IACrB,QAAQ,EAAE,KAAK;IACf,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,OAAO;IAClB,IAAI,EAAE,KAAK;IACX,GAAG,EAAE,iBAAiB;IACtB,OAAO,EAAE,0EAA0E;CACpF,CAAC;AAEF,4DAA4D;AAC5D,MAAM,CAAC,MAAM,cAAc,GAAa;IACtC,EAAE,EAAE,eAAe;IACnB,WAAW,EAAE,8EAA8E;IAC3F,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE,QAAQ;IAClB,KAAK,EAAE;QACL,kBAAkB;QAClB,mBAAmB;QACnB,iBAAiB;QACjB,aAAa;QACb,WAAW;QACX,UAAU;QACV,cAAc;QACd,YAAY;QACZ,aAAa;KACd;IACD,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,iBAAiB,CAAC;IACpD,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE;QACtB,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,CAAC,EAAU,EAAE,IAAc,EAAE,EAAE,CACzC,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAC3B,QAAQ,CAAC,IAAI,CACX,eAAe,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CACnF,CACF,CAAC;QAEJ,GAAG,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;QAC1C,GAAG,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,CAAC;QAC5C,GAAG,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;QACxC,GAAG,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QAChC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAC5B,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC1B,GAAG,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QAClC,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAC9B,GAAG,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QAEhC,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"python.js","sourceRoot":"","sources":["../../src/detectors/python.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Source-code detector for classical, non-quantum-safe asymmetric cryptography\n * in Python. Same lexical (regex-over-source) strategy as the JS/TS detectors:\n * robust to formatting, dependency-free, and confidence-tagged per pattern.\n *\n * Covers the three libraries that carry ~all real-world Python asymmetric\n * crypto:\n * - `cryptography` (hazmat): rsa/ec/dh/x25519/x448/ed25519/ed448 + OAEP padding\n * - PyCryptodome (`Crypto.PublicKey`): RSA/ECC/DSA generate + PKCS1_OAEP\n * - paramiko (SSH): RSAKey / ECDSAKey / Ed25519Key / DSSKey\n *\n * JWT/JOSE algorithm strings (`algorithm=\"RS256\"`) are NOT handled here — the\n * language-agnostic `jwt-jose` detector now applies to Python too (a quoted\n * `\"RS256\"` is the same evidence in any language).\n *\n * HNDL policy mirrors the JS detectors: key agreement / KEM (RSA-OAEP, ECDH, DH,\n * X25519/X448) is harvest-now-decrypt-later exposed (hndl:true); signatures\n * (ECDSA, DSA, Ed25519/Ed448) are hndl:false but still high/low severity because\n * a quantum attacker can forge them. EC key generation is ambiguous (an EC key\n * feeds both ECDSA and ECDH), so it is classified conservatively as\n * key-exchange-capable (hndl:true), exactly as the Node `ec` keygen rule is.\n */\nimport type { Detector, Finding, RuleMeta } from \"../types.js\";\nimport { PYTHON_EXTENSIONS, eachMatch, findingFromRule, hasExtension } from \"../detect-utils.js\";\nimport { CWE_BROKEN_CRYPTO, CWE_CERT_VALIDATION, CWE_WEAK_STRENGTH } from \"../cwe.js\";\n\n/* -------------------------------------------------------------------------- */\n/* Precompiled regexes (module scope) */\n/* -------------------------------------------------------------------------- */\n\n// RSA key generation: cryptography `rsa.generate_private_key(`, PyCryptodome\n// `RSA.generate(`, paramiko `paramiko.RSAKey` / `RSAKey.generate(`.\nconst RE_PY_RSA_KEYGEN =\n /\\brsa\\.generate_private_key\\s*\\(|\\bRSA\\.generate\\s*\\(|\\bparamiko\\.RSAKey\\b|\\bRSAKey\\.generate\\s*\\(/g;\n// RSA public-key encryption padding (RSA-OAEP): confidentiality → HNDL.\nconst RE_PY_RSA_ENCRYPT = /\\bpadding\\.OAEP\\s*\\(|\\bPKCS1_OAEP\\.new\\s*\\(/g;\n// EC key generation (ambiguous ECDSA/ECDH): cryptography + PyCryptodome.\nconst RE_PY_EC_KEYGEN = /\\bec\\.generate_private_key\\s*\\(|\\bECC\\.generate\\s*\\(/g;\n// ECDSA signatures: cryptography `ec.ECDSA(`, paramiko ECDSAKey.\nconst RE_PY_ECDSA = /\\bec\\.ECDSA\\s*\\(|\\bparamiko\\.ECDSAKey\\b|\\bECDSAKey\\.generate\\s*\\(/g;\n// ECDH key agreement: cryptography `ec.ECDH(` — the actual harvest-now event in\n// `private_key.exchange(ec.ECDH(), peer)`; previously missed entirely (audit F3).\nconst RE_PY_ECDH = /\\bec\\.ECDH\\s*\\(/g;\n// DSA: PyCryptodome `DSA.generate(`, paramiko DSSKey.\nconst RE_PY_DSA = /\\bDSA\\.generate\\s*\\(|\\bparamiko\\.DSSKey\\b|\\bDSSKey\\.generate\\s*\\(/g;\n// hazmat DSA: cryptography `dsa.generate_private_key(` — the `cryptography` DSA\n// keygen path (lowercase module) that RE_PY_DSA's uppercase `DSA.generate` misses\n// (audit F9-python).\nconst RE_PY_HAZMAT_DSA = /\\bdsa\\.generate_private_key\\s*\\(/g;\n// Finite-field Diffie-Hellman (cryptography `dh`).\nconst RE_PY_DH = /\\bdh\\.generate_parameters\\s*\\(|\\bdh\\.DHParameterNumbers\\s*\\(/g;\n// Modern-but-classical curve primitives (cryptography). `.generate(` anchors so\n// a bare import of the class name does not fire.\nconst RE_PY_X25519 = /\\bX25519PrivateKey\\.generate\\s*\\(/g;\nconst RE_PY_X448 = /\\bX448PrivateKey\\.generate\\s*\\(/g;\nconst RE_PY_EDDSA = /\\b(?:Ed25519|Ed448)PrivateKey\\.generate\\s*\\(|\\bparamiko\\.Ed25519Key\\b/g;\n\n// Python TLS misconfiguration. Mirrors the JS `tlsDetector` split of source.ts:\n// certificate-verification bypass (requests `verify=False`, `ssl.CERT_NONE`,\n// `check_hostname=False`, `ssl._create_unverified_context(`) is the high-severity\n// MITM surface (CWE-295); a pinned legacy protocol (`ssl.PROTOCOL_TLSv1`) is the\n// medium-severity weak-strength surface (CWE-326).\nconst RE_PY_TLS_REJECT =\n /\\bverify\\s*=\\s*False\\b|\\bssl\\.CERT_NONE\\b|\\bcheck_hostname\\s*=\\s*False\\b|\\bssl\\._create_unverified_context\\s*\\(/g;\nconst RE_PY_TLS_LEGACY = /\\bPROTOCOL_TLSv1\\b/g;\n\n/* -------------------------------------------------------------------------- */\n/* Rule catalog */\n/* -------------------------------------------------------------------------- */\n\nconst RULE_PY_RSA_KEYGEN: RuleMeta = {\n id: \"python-rsa-keygen\",\n title: \"Python RSA key generation\",\n description:\n \"cryptography rsa.generate_private_key / PyCryptodome RSA.generate / paramiko RSAKey\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Generates a classical RSA key pair (Python), which is not quantum-safe.\",\n};\nconst RULE_PY_RSA_ENCRYPT: RuleMeta = {\n id: \"python-rsa-encrypt\",\n title: \"Python RSA public-key encryption\",\n description: \"RSA-OAEP / PKCS1_OAEP encryption padding\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"RSA public-key encryption (OAEP) is broken by Shor's algorithm and exposed to harvest-now-decrypt-later.\",\n};\nconst RULE_PY_EC_KEYGEN: RuleMeta = {\n id: \"python-ec-keygen\",\n title: \"Python EC key generation\",\n description: \"cryptography ec.generate_private_key / PyCryptodome ECC.generate\",\n category: \"key-exchange\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDH\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Generates a classical EC key pair (Python). EC keys feed BOTH ECDSA signatures and ECDH key agreement; the ECDH path is harvest-now-decrypt-later exposed.\",\n remediation:\n \"For key agreement: hybrid X25519MLKEM768 (ML-KEM-768). For signatures: ML-DSA-65 (FIPS 204).\",\n};\nconst RULE_PY_ECDSA: RuleMeta = {\n id: \"python-ecdsa\",\n title: \"Python ECDSA signature\",\n description: \"cryptography ec.ECDSA / paramiko ECDSAKey\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"medium\",\n algorithm: \"ECDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical ECDSA signing (Python) is forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_PY_ECDH: RuleMeta = {\n id: \"python-ecdh\",\n title: \"Python ECDH key agreement\",\n description: \"cryptography ec.ECDH() exchange\",\n category: \"key-exchange\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDH\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Elliptic-curve Diffie-Hellman key agreement (Python) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_PY_DSA: RuleMeta = {\n id: \"python-dsa\",\n title: \"Python DSA key/usage\",\n description: \"PyCryptodome DSA.generate / paramiko DSSKey\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"DSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical DSA (Python) is deprecated and forgeable by a quantum attacker.\",\n remediation: \"Rotate off DSA and migrate to ML-DSA-65 (FIPS 204).\",\n};\nconst RULE_PY_HAZMAT_DSA: RuleMeta = {\n id: \"python-hazmat-dsa\",\n title: \"Python DSA key generation (cryptography)\",\n description: \"cryptography dsa.generate_private_key\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"DSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"cryptography dsa.generate_private_key (Python) creates a classical DSA key; DSA is deprecated and forgeable by a quantum attacker.\",\n remediation: \"Rotate off DSA and migrate to ML-DSA-65 (FIPS 204).\",\n};\nconst RULE_PY_DH: RuleMeta = {\n id: \"python-dh\",\n title: \"Python Diffie-Hellman key exchange\",\n description: \"cryptography dh.generate_parameters / DHParameterNumbers\",\n category: \"key-exchange\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"DH\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Finite-field Diffie-Hellman (Python) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_PY_X25519: RuleMeta = {\n id: \"python-x25519\",\n title: \"Python X25519 key exchange\",\n description: \"cryptography X25519PrivateKey.generate\",\n category: \"key-exchange\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"X25519\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"X25519 (Python) is modern but still classical key agreement — harvest-now-decrypt-later.\",\n};\nconst RULE_PY_X448: RuleMeta = {\n id: \"python-x448\",\n title: \"Python X448 key exchange\",\n description: \"cryptography X448PrivateKey.generate\",\n category: \"key-exchange\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"X448\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"X448 (Python) is modern but still classical key agreement — harvest-now-decrypt-later.\",\n};\nconst RULE_PY_EDDSA: RuleMeta = {\n id: \"python-eddsa\",\n title: \"Python Ed25519/Ed448 signature\",\n description: \"cryptography Ed25519/Ed448 PrivateKey.generate / paramiko Ed25519Key\",\n category: \"signature\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"EdDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Ed25519/Ed448 (Python) is a modern but still classical signature scheme.\",\n};\nconst RULE_PY_TLS_REJECT: RuleMeta = {\n id: \"python-tls-reject\",\n title: \"Python TLS certificate verification disabled\",\n description:\n \"requests verify=False / ssl.CERT_NONE / check_hostname=False / _create_unverified_context\",\n category: \"tls\",\n severity: \"high\",\n confidence: \"high\",\n hndl: false,\n cwe: CWE_CERT_VALIDATION,\n message:\n \"TLS certificate verification is disabled (verify=False / CERT_NONE / check_hostname=False / _create_unverified_context), which allows man-in-the-middle attacks.\",\n remediation:\n \"Enable certificate verification (verify=True, ssl.CERT_REQUIRED, check_hostname=True) and verify certificates properly.\",\n};\nconst RULE_PY_TLS_LEGACY: RuleMeta = {\n id: \"python-tls-legacy-version\",\n title: \"Python legacy TLS version pinned\",\n description: \"ssl.PROTOCOL_TLSv1 (TLS 1.0)\",\n category: \"tls\",\n severity: \"medium\",\n confidence: \"high\",\n hndl: false,\n cwe: CWE_WEAK_STRENGTH,\n message: \"TLS 1.0 (ssl.PROTOCOL_TLSv1) is deprecated and insecure; require TLS 1.3.\",\n remediation:\n \"Use ssl.PROTOCOL_TLS_CLIENT with minimum_version = ssl.TLSVersion.TLSv1_3 and prefer PQC-hybrid key exchange.\",\n};\n\n/** Detects classical asymmetric crypto in Python source. */\nexport const pythonDetector: Detector = {\n id: \"python-crypto\",\n description: \"Classical asymmetric crypto in Python (cryptography, PyCryptodome, paramiko)\",\n scope: \"source\",\n language: \"python\",\n rules: [\n RULE_PY_RSA_KEYGEN,\n RULE_PY_RSA_ENCRYPT,\n RULE_PY_EC_KEYGEN,\n RULE_PY_ECDSA,\n RULE_PY_ECDH,\n RULE_PY_DSA,\n RULE_PY_HAZMAT_DSA,\n RULE_PY_DH,\n RULE_PY_X25519,\n RULE_PY_X448,\n RULE_PY_EDDSA,\n RULE_PY_TLS_REJECT,\n RULE_PY_TLS_LEGACY,\n ],\n appliesTo: (f) => hasExtension(f, PYTHON_EXTENSIONS),\n detect({ file, content }): Finding[] {\n const findings: Finding[] = [];\n const add = (re: RegExp, rule: RuleMeta) =>\n eachMatch(re, content, (m) =>\n findings.push(\n findingFromRule(rule, { file, content, index: m.index, matchLength: m[0].length }),\n ),\n );\n\n add(RE_PY_RSA_KEYGEN, RULE_PY_RSA_KEYGEN);\n add(RE_PY_RSA_ENCRYPT, RULE_PY_RSA_ENCRYPT);\n add(RE_PY_EC_KEYGEN, RULE_PY_EC_KEYGEN);\n add(RE_PY_ECDSA, RULE_PY_ECDSA);\n add(RE_PY_ECDH, RULE_PY_ECDH);\n add(RE_PY_DSA, RULE_PY_DSA);\n add(RE_PY_HAZMAT_DSA, RULE_PY_HAZMAT_DSA);\n add(RE_PY_DH, RULE_PY_DH);\n add(RE_PY_X25519, RULE_PY_X25519);\n add(RE_PY_X448, RULE_PY_X448);\n add(RE_PY_EDDSA, RULE_PY_EDDSA);\n add(RE_PY_TLS_REJECT, RULE_PY_TLS_REJECT);\n add(RE_PY_TLS_LEGACY, RULE_PY_TLS_LEGACY);\n\n return findings;\n },\n};\n"]}