@quantakrypto/core 0.4.3 → 0.5.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 (314) hide show
  1. package/README.md +76 -27
  2. package/dist/cbom-merge.d.ts +9 -0
  3. package/dist/cbom-merge.d.ts.map +1 -0
  4. package/dist/cbom-merge.js +121 -0
  5. package/dist/cbom-merge.js.map +1 -0
  6. package/dist/cbom.d.ts +5 -0
  7. package/dist/cbom.d.ts.map +1 -1
  8. package/dist/cbom.js +132 -37
  9. package/dist/cbom.js.map +1 -1
  10. package/dist/comments.d.ts +6 -26
  11. package/dist/comments.d.ts.map +1 -1
  12. package/dist/comments.js +77 -38
  13. package/dist/comments.js.map +1 -1
  14. package/dist/dependencies.d.ts.map +1 -1
  15. package/dist/dependencies.js +1 -1
  16. package/dist/dependencies.js.map +1 -1
  17. package/dist/detect-utils.d.ts +59 -21
  18. package/dist/detect-utils.d.ts.map +1 -1
  19. package/dist/detect-utils.js +143 -8
  20. package/dist/detect-utils.js.map +1 -1
  21. package/dist/detectors/age.d.ts +16 -0
  22. package/dist/detectors/age.d.ts.map +1 -0
  23. package/dist/detectors/age.js +40 -0
  24. package/dist/detectors/age.js.map +1 -0
  25. package/dist/detectors/ansible.d.ts +13 -0
  26. package/dist/detectors/ansible.d.ts.map +1 -0
  27. package/dist/detectors/ansible.js +108 -0
  28. package/dist/detectors/ansible.js.map +1 -0
  29. package/dist/detectors/bicep.d.ts +20 -0
  30. package/dist/detectors/bicep.d.ts.map +1 -0
  31. package/dist/detectors/bicep.js +74 -0
  32. package/dist/detectors/bicep.js.map +1 -0
  33. package/dist/detectors/c.d.ts +4 -2
  34. package/dist/detectors/c.d.ts.map +1 -1
  35. package/dist/detectors/c.js +222 -4
  36. package/dist/detectors/c.js.map +1 -1
  37. package/dist/detectors/cicd.d.ts +27 -0
  38. package/dist/detectors/cicd.d.ts.map +1 -0
  39. package/dist/detectors/cicd.js +129 -0
  40. package/dist/detectors/cicd.js.map +1 -0
  41. package/dist/detectors/cloud-kms.d.ts +24 -0
  42. package/dist/detectors/cloud-kms.d.ts.map +1 -0
  43. package/dist/detectors/cloud-kms.js +99 -0
  44. package/dist/detectors/cloud-kms.js.map +1 -0
  45. package/dist/detectors/cloudformation.d.ts +38 -0
  46. package/dist/detectors/cloudformation.d.ts.map +1 -0
  47. package/dist/detectors/cloudformation.js +201 -0
  48. package/dist/detectors/cloudformation.js.map +1 -0
  49. package/dist/detectors/codesign.d.ts +50 -0
  50. package/dist/detectors/codesign.d.ts.map +1 -0
  51. package/dist/detectors/codesign.js +143 -0
  52. package/dist/detectors/codesign.js.map +1 -0
  53. package/dist/detectors/csharp.d.ts.map +1 -1
  54. package/dist/detectors/csharp.js +13 -3
  55. package/dist/detectors/csharp.js.map +1 -1
  56. package/dist/detectors/dart.d.ts +35 -0
  57. package/dist/detectors/dart.d.ts.map +1 -0
  58. package/dist/detectors/dart.js +177 -0
  59. package/dist/detectors/dart.js.map +1 -0
  60. package/dist/detectors/database.d.ts +19 -0
  61. package/dist/detectors/database.d.ts.map +1 -0
  62. package/dist/detectors/database.js +97 -0
  63. package/dist/detectors/database.js.map +1 -0
  64. package/dist/detectors/dkim.d.ts +54 -0
  65. package/dist/detectors/dkim.d.ts.map +1 -0
  66. package/dist/detectors/dkim.js +92 -0
  67. package/dist/detectors/dkim.js.map +1 -0
  68. package/dist/detectors/dnssec.d.ts +55 -0
  69. package/dist/detectors/dnssec.d.ts.map +1 -0
  70. package/dist/detectors/dnssec.js +116 -0
  71. package/dist/detectors/dnssec.js.map +1 -0
  72. package/dist/detectors/elixir.d.ts +20 -0
  73. package/dist/detectors/elixir.d.ts.map +1 -0
  74. package/dist/detectors/elixir.js +227 -0
  75. package/dist/detectors/elixir.js.map +1 -0
  76. package/dist/detectors/java.d.ts.map +1 -1
  77. package/dist/detectors/java.js +34 -4
  78. package/dist/detectors/java.js.map +1 -1
  79. package/dist/detectors/jose.d.ts +20 -0
  80. package/dist/detectors/jose.d.ts.map +1 -0
  81. package/dist/detectors/jose.js +72 -0
  82. package/dist/detectors/jose.js.map +1 -0
  83. package/dist/detectors/jwk.d.ts +25 -0
  84. package/dist/detectors/jwk.d.ts.map +1 -0
  85. package/dist/detectors/jwk.js +131 -0
  86. package/dist/detectors/jwk.js.map +1 -0
  87. package/dist/detectors/k8s.d.ts +17 -0
  88. package/dist/detectors/k8s.d.ts.map +1 -0
  89. package/dist/detectors/k8s.js +88 -0
  90. package/dist/detectors/k8s.js.map +1 -0
  91. package/dist/detectors/keystore.d.ts +19 -0
  92. package/dist/detectors/keystore.d.ts.map +1 -0
  93. package/dist/detectors/keystore.js +76 -0
  94. package/dist/detectors/keystore.js.map +1 -0
  95. package/dist/detectors/mesh.d.ts +34 -0
  96. package/dist/detectors/mesh.d.ts.map +1 -0
  97. package/dist/detectors/mesh.js +91 -0
  98. package/dist/detectors/mesh.js.map +1 -0
  99. package/dist/detectors/messaging.d.ts +16 -0
  100. package/dist/detectors/messaging.d.ts.map +1 -0
  101. package/dist/detectors/messaging.js +79 -0
  102. package/dist/detectors/messaging.js.map +1 -0
  103. package/dist/detectors/objc.d.ts +41 -0
  104. package/dist/detectors/objc.d.ts.map +1 -0
  105. package/dist/detectors/objc.js +146 -0
  106. package/dist/detectors/objc.js.map +1 -0
  107. package/dist/detectors/openpgp.d.ts +20 -0
  108. package/dist/detectors/openpgp.d.ts.map +1 -0
  109. package/dist/detectors/openpgp.js +151 -0
  110. package/dist/detectors/openpgp.js.map +1 -0
  111. package/dist/detectors/pem.d.ts.map +1 -1
  112. package/dist/detectors/pem.js +33 -1
  113. package/dist/detectors/pem.js.map +1 -1
  114. package/dist/detectors/php.d.ts +25 -0
  115. package/dist/detectors/php.d.ts.map +1 -0
  116. package/dist/detectors/php.js +171 -0
  117. package/dist/detectors/php.js.map +1 -0
  118. package/dist/detectors/pkcs11.d.ts +17 -0
  119. package/dist/detectors/pkcs11.d.ts.map +1 -0
  120. package/dist/detectors/pkcs11.js +87 -0
  121. package/dist/detectors/pkcs11.js.map +1 -0
  122. package/dist/detectors/proxy.d.ts +52 -0
  123. package/dist/detectors/proxy.d.ts.map +1 -0
  124. package/dist/detectors/proxy.js +157 -0
  125. package/dist/detectors/proxy.js.map +1 -0
  126. package/dist/detectors/pulumi.d.ts +19 -0
  127. package/dist/detectors/pulumi.d.ts.map +1 -0
  128. package/dist/detectors/pulumi.js +80 -0
  129. package/dist/detectors/pulumi.js.map +1 -0
  130. package/dist/detectors/python.d.ts.map +1 -1
  131. package/dist/detectors/python.js +70 -0
  132. package/dist/detectors/python.js.map +1 -1
  133. package/dist/detectors/rust.d.ts.map +1 -1
  134. package/dist/detectors/rust.js +73 -0
  135. package/dist/detectors/rust.js.map +1 -1
  136. package/dist/detectors/secrets.d.ts +24 -0
  137. package/dist/detectors/secrets.d.ts.map +1 -0
  138. package/dist/detectors/secrets.js +63 -0
  139. package/dist/detectors/secrets.js.map +1 -0
  140. package/dist/detectors/solidity.d.ts +50 -0
  141. package/dist/detectors/solidity.d.ts.map +1 -0
  142. package/dist/detectors/solidity.js +108 -0
  143. package/dist/detectors/solidity.js.map +1 -0
  144. package/dist/detectors/source.d.ts.map +1 -1
  145. package/dist/detectors/source.js +243 -53
  146. package/dist/detectors/source.js.map +1 -1
  147. package/dist/detectors/spire.d.ts +49 -0
  148. package/dist/detectors/spire.d.ts.map +1 -0
  149. package/dist/detectors/spire.js +77 -0
  150. package/dist/detectors/spire.js.map +1 -0
  151. package/dist/detectors/ssh-ca.d.ts +72 -0
  152. package/dist/detectors/ssh-ca.d.ts.map +1 -0
  153. package/dist/detectors/ssh-ca.js +119 -0
  154. package/dist/detectors/ssh-ca.js.map +1 -0
  155. package/dist/detectors/stateful-hbs.d.ts.map +1 -1
  156. package/dist/detectors/stateful-hbs.js +9 -6
  157. package/dist/detectors/stateful-hbs.js.map +1 -1
  158. package/dist/detectors/supply-chain.d.ts +17 -0
  159. package/dist/detectors/supply-chain.d.ts.map +1 -0
  160. package/dist/detectors/supply-chain.js +89 -0
  161. package/dist/detectors/supply-chain.js.map +1 -0
  162. package/dist/detectors/swift.d.ts +22 -0
  163. package/dist/detectors/swift.d.ts.map +1 -0
  164. package/dist/detectors/swift.js +120 -0
  165. package/dist/detectors/swift.js.map +1 -0
  166. package/dist/detectors/terraform.d.ts +21 -0
  167. package/dist/detectors/terraform.d.ts.map +1 -0
  168. package/dist/detectors/terraform.js +150 -0
  169. package/dist/detectors/terraform.js.map +1 -0
  170. package/dist/detectors/vault.d.ts +15 -0
  171. package/dist/detectors/vault.d.ts.map +1 -0
  172. package/dist/detectors/vault.js +97 -0
  173. package/dist/detectors/vault.js.map +1 -0
  174. package/dist/detectors/vpn.d.ts +22 -0
  175. package/dist/detectors/vpn.d.ts.map +1 -0
  176. package/dist/detectors/vpn.js +73 -0
  177. package/dist/detectors/vpn.js.map +1 -0
  178. package/dist/detectors/weak-hash.d.ts +71 -0
  179. package/dist/detectors/weak-hash.d.ts.map +1 -0
  180. package/dist/detectors/weak-hash.js +116 -0
  181. package/dist/detectors/weak-hash.js.map +1 -0
  182. package/dist/detectors/webauthn.d.ts +61 -0
  183. package/dist/detectors/webauthn.d.ts.map +1 -0
  184. package/dist/detectors/webauthn.js +109 -0
  185. package/dist/detectors/webauthn.js.map +1 -0
  186. package/dist/detectors/xmldsig.d.ts +23 -0
  187. package/dist/detectors/xmldsig.d.ts.map +1 -0
  188. package/dist/detectors/xmldsig.js +84 -0
  189. package/dist/detectors/xmldsig.js.map +1 -0
  190. package/dist/evidence.d.ts +79 -4
  191. package/dist/evidence.d.ts.map +1 -1
  192. package/dist/evidence.js +76 -0
  193. package/dist/evidence.js.map +1 -1
  194. package/dist/index.d.ts +17 -9
  195. package/dist/index.d.ts.map +1 -1
  196. package/dist/index.js +21 -9
  197. package/dist/index.js.map +1 -1
  198. package/dist/inventory.d.ts +0 -2
  199. package/dist/inventory.d.ts.map +1 -1
  200. package/dist/inventory.js +15 -6
  201. package/dist/inventory.js.map +1 -1
  202. package/dist/policy.d.ts +67 -0
  203. package/dist/policy.d.ts.map +1 -0
  204. package/dist/policy.js +115 -0
  205. package/dist/policy.js.map +1 -0
  206. package/dist/registry.d.ts +9 -4
  207. package/dist/registry.d.ts.map +1 -1
  208. package/dist/registry.js +81 -4
  209. package/dist/registry.js.map +1 -1
  210. package/dist/remediate-pipeline.d.ts +0 -3
  211. package/dist/remediate-pipeline.d.ts.map +1 -1
  212. package/dist/remediate-pipeline.js +23 -2
  213. package/dist/remediate-pipeline.js.map +1 -1
  214. package/dist/remediation.d.ts +10 -0
  215. package/dist/remediation.d.ts.map +1 -1
  216. package/dist/remediation.js +32 -0
  217. package/dist/remediation.js.map +1 -1
  218. package/dist/report.d.ts +9 -0
  219. package/dist/report.d.ts.map +1 -1
  220. package/dist/report.js +38 -1
  221. package/dist/report.js.map +1 -1
  222. package/dist/scan-worker.js +5 -3
  223. package/dist/scan-worker.js.map +1 -1
  224. package/dist/scan.d.ts.map +1 -1
  225. package/dist/scan.js +35 -6
  226. package/dist/scan.js.map +1 -1
  227. package/dist/standards-profiles.d.ts +58 -0
  228. package/dist/standards-profiles.d.ts.map +1 -0
  229. package/dist/standards-profiles.js +100 -0
  230. package/dist/standards-profiles.js.map +1 -0
  231. package/dist/standards.d.ts +96 -0
  232. package/dist/standards.d.ts.map +1 -0
  233. package/dist/standards.js +107 -0
  234. package/dist/standards.js.map +1 -0
  235. package/dist/types.d.ts +6 -5
  236. package/dist/types.d.ts.map +1 -1
  237. package/dist/types.js.map +1 -1
  238. package/dist/version.d.ts +1 -1
  239. package/dist/version.js +1 -1
  240. package/dist/version.js.map +1 -1
  241. package/dist/vex.d.ts +39 -0
  242. package/dist/vex.d.ts.map +1 -0
  243. package/dist/vex.js +87 -0
  244. package/dist/vex.js.map +1 -0
  245. package/dist/walk.d.ts +8 -3
  246. package/dist/walk.d.ts.map +1 -1
  247. package/dist/walk.js +32 -1
  248. package/dist/walk.js.map +1 -1
  249. package/package.json +1 -1
  250. package/src/cbom-merge.ts +146 -0
  251. package/src/cbom.ts +153 -39
  252. package/src/comments.ts +84 -39
  253. package/src/dependencies.ts +2 -1
  254. package/src/detect-utils.ts +146 -12
  255. package/src/detectors/age.ts +60 -0
  256. package/src/detectors/ansible.ts +140 -0
  257. package/src/detectors/bicep.ts +107 -0
  258. package/src/detectors/c.ts +240 -6
  259. package/src/detectors/cicd.ts +171 -0
  260. package/src/detectors/cloud-kms.ts +141 -0
  261. package/src/detectors/cloudformation.ts +250 -0
  262. package/src/detectors/codesign.ts +214 -0
  263. package/src/detectors/csharp.ts +13 -3
  264. package/src/detectors/dart.ts +237 -0
  265. package/src/detectors/database.ts +141 -0
  266. package/src/detectors/dkim.ts +172 -0
  267. package/src/detectors/dnssec.ts +195 -0
  268. package/src/detectors/elixir.ts +268 -0
  269. package/src/detectors/java.ts +39 -4
  270. package/src/detectors/jose.ts +110 -0
  271. package/src/detectors/jwk.ts +170 -0
  272. package/src/detectors/k8s.ts +115 -0
  273. package/src/detectors/keystore.ts +109 -0
  274. package/src/detectors/mesh.ts +130 -0
  275. package/src/detectors/messaging.ts +106 -0
  276. package/src/detectors/objc.ts +209 -0
  277. package/src/detectors/openpgp.ts +194 -0
  278. package/src/detectors/pem.ts +31 -1
  279. package/src/detectors/php.ts +230 -0
  280. package/src/detectors/pkcs11.ts +113 -0
  281. package/src/detectors/proxy.ts +236 -0
  282. package/src/detectors/pulumi.ts +106 -0
  283. package/src/detectors/python.ts +71 -0
  284. package/src/detectors/rust.ts +76 -0
  285. package/src/detectors/secrets.ts +103 -0
  286. package/src/detectors/solidity.ts +176 -0
  287. package/src/detectors/source.ts +283 -73
  288. package/src/detectors/spire.ts +143 -0
  289. package/src/detectors/ssh-ca.ts +215 -0
  290. package/src/detectors/stateful-hbs.ts +9 -6
  291. package/src/detectors/supply-chain.ts +117 -0
  292. package/src/detectors/swift.ts +149 -0
  293. package/src/detectors/terraform.ts +188 -0
  294. package/src/detectors/vault.ts +120 -0
  295. package/src/detectors/vpn.ts +103 -0
  296. package/src/detectors/weak-hash.ts +217 -0
  297. package/src/detectors/webauthn.ts +205 -0
  298. package/src/detectors/xmldsig.ts +115 -0
  299. package/src/evidence.ts +138 -4
  300. package/src/index.ts +50 -12
  301. package/src/inventory.ts +15 -7
  302. package/src/policy.ts +180 -0
  303. package/src/registry.ts +81 -4
  304. package/src/remediate-pipeline.ts +26 -3
  305. package/src/remediation.ts +39 -0
  306. package/src/report.ts +43 -1
  307. package/src/scan-worker.ts +5 -3
  308. package/src/scan.ts +41 -6
  309. package/src/standards-profiles.ts +136 -0
  310. package/src/standards.ts +186 -0
  311. package/src/types.ts +11 -4
  312. package/src/version.ts +1 -1
  313. package/src/vex.ts +122 -0
  314. package/src/walk.ts +33 -2
@@ -1 +1 @@
1
- {"version":3,"file":"rust.js","sourceRoot":"","sources":["../../src/detectors/rust.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Source-code detector for classical asymmetric cryptography in Rust. Covers the\n * common crypto crates: `rsa`, `ring`, the `*-dalek` family (ed25519/x25519),\n * the RustCrypto elliptic-curve crates (`p256`/`p384`/`k256`), and the `openssl`\n * crate bindings. Lexical, same strategy as the other packs; the `::` path\n * syntax makes the signals precise.\n *\n * HNDL: RSA encryption and (EC/X)DH key agreement are harvest-now-decrypt-later\n * exposed (hndl:true); ECDSA / DSA / Ed25519 signatures are hndl:false but\n * forgeable. `openssl::EcKey` keygen is ambiguous (feeds ECDSA + ECDH),\n * classified conservatively as key-exchange-capable (hndl:true). Also flags\n * Rust TLS certificate-validation bypasses (reqwest / rustls) — not quantum but\n * mirrors the JS tlsDetector's cert-validation category.\n */\nimport type { AlgorithmFamily, Detector, Finding, RuleMeta } from \"../types.js\";\nimport { RUST_EXTENSIONS, eachMatch, findingFromRule, hasExtension } from \"../detect-utils.js\";\nimport { CWE_BROKEN_CRYPTO, CWE_CERT_VALIDATION } from \"../cwe.js\";\n\n// `rsa` crate + ring RsaKeyPair. `::` after the type marks an associated-fn call.\nconst RE_RUST_RSA = /\\b(?:RsaPrivateKey|RsaPublicKey|RsaKeyPair)::/g;\n// ECDSA: RustCrypto `p256::ecdsa::SigningKey` (contains `ecdsa::SigningKey`),\n// ring `EcdsaKeyPair::`, or a bare `ecdsa::SigningKey`.\nconst RE_RUST_ECDSA = /\\becdsa::SigningKey\\b|\\bEcdsaKeyPair::/g;\n// ECDH: RustCrypto `p256::ecdh::EphemeralSecret`, ring agreement / ECDH_P*.\nconst RE_RUST_ECDH = /\\becdh::EphemeralSecret\\b|\\bagreement::ECDH_P(?:256|384)\\b/g;\n// Ed25519 signatures (dalek + ring).\nconst RE_RUST_ED25519 = /\\bed25519_dalek::(?:SigningKey|Keypair|SecretKey)\\b|\\bEd25519KeyPair::/g;\n// X25519 key agreement (dalek).\nconst RE_RUST_X25519 = /\\bx25519_dalek::(?:EphemeralSecret|StaticSecret)\\b/g;\n// openssl crate bindings — the `Type::generate(` / `Dh::` call forms, distinct\n// from the ring / RustCrypto path syntax above (audit F5/F9 false-negatives).\nconst RE_RUST_OPENSSL_RSA = /\\bRsa::generate\\s*\\(/g;\nconst RE_RUST_OPENSSL_EC = /\\bEcKey::generate\\s*\\(/g;\nconst RE_RUST_OPENSSL_DSA = /\\bDsa::generate\\s*\\(/g;\nconst RE_RUST_OPENSSL_DH = /\\bDh::/g;\n// ring X25519 agreement (the ECDH_P* forms are handled by RE_RUST_ECDH above).\nconst RE_RUST_RING_X25519 = /\\bagreement::X25519\\b/g;\n// Bare (unqualified) constructors: a braced `use x25519_dalek::{EphemeralSecret}`\n// / `use ed25519_dalek::{SigningKey}` strips the `::` path prefix, defeating the\n// path-qualified rules above. The `(?<![:\\w])` lookbehind keeps these from\n// double-matching the qualified forms (e.g. `p256::ecdsa::SigningKey::random`).\nconst RE_RUST_BARE_X25519 = /(?<![:\\w])EphemeralSecret::new\\s*\\(/g;\nconst RE_RUST_BARE_SIGNINGKEY = /(?<![:\\w])SigningKey::(?:generate|random)\\s*\\(/g;\n// jsonwebtoken crate `Algorithm` enum variants selecting a classical JWT signer:\n// RSASSA-PKCS1 (RS*), RSASSA-PSS (PS*), ECDSA (ES*), and Ed25519 (EdDSA). The\n// `\\s*` between `Algorithm` and `::` catches the variant split across lines /\n// routed through a helper (audit token_policy false-negative); the required\n// suffix keeps it off unrelated `Algorithm::` uses (e.g. `HS256` HMAC, which is\n// symmetric and not quantum-vulnerable, or `Algorithm::new`).\nconst RE_RUST_JWT_ALG = /\\bAlgorithm\\s*::(RS|PS|ES)(?:256|384|512)\\b|\\bAlgorithm\\s*::EdDSA\\b/g;\n// Rust TLS certificate-validation bypass: reqwest `danger_accept_invalid_certs`\n// and the rustls `.dangerous()` escape hatch. Mirrors the JS tlsDetector.\nconst RE_RUST_TLS_ACCEPT_INVALID = /\\bdanger_accept_invalid_certs\\s*\\(\\s*true/g;\nconst RE_RUST_TLS_DANGEROUS = /\\.dangerous\\s*\\(\\s*\\)/g;\n\nconst RULE_RUST_RSA: RuleMeta = {\n id: \"rust-rsa\",\n title: \"Rust RSA key/usage\",\n description: \"the `rsa` crate / ring RsaKeyPair\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical RSA (Rust) is not quantum-safe and RSA encryption is HNDL-exposed.\",\n};\nconst RULE_RUST_ECDSA: RuleMeta = {\n id: \"rust-ecdsa\",\n title: \"Rust ECDSA signature\",\n description: \"p256/p384/k256 ecdsa::SigningKey / ring EcdsaKeyPair\",\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 (Rust) is forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_RUST_ECDH: RuleMeta = {\n id: \"rust-ecdh\",\n title: \"Rust ECDH key agreement\",\n description: \"p256/p384 ecdh::EphemeralSecret / ring agreement\",\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 (Rust) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_RUST_ED25519: RuleMeta = {\n id: \"rust-ed25519\",\n title: \"Rust Ed25519 signature\",\n description: \"ed25519-dalek SigningKey/Keypair / ring Ed25519KeyPair\",\n category: \"signature\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"EdDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Ed25519 (Rust) is a modern but still classical signature scheme.\",\n};\nconst RULE_RUST_X25519: RuleMeta = {\n id: \"rust-x25519\",\n title: \"Rust X25519 key agreement\",\n description: \"x25519-dalek EphemeralSecret/StaticSecret\",\n category: \"key-exchange\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"X25519\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"X25519 (Rust) is modern but still classical key agreement — harvest-now-decrypt-later.\",\n};\nconst RULE_RUST_OPENSSL_RSA: RuleMeta = {\n id: \"rust-openssl-rsa\",\n title: \"Rust openssl RSA key generation\",\n description: \"openssl crate Rsa::generate\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Generates a classical RSA key pair via the Rust `openssl` crate — not quantum-safe and RSA encryption is HNDL-exposed.\",\n};\nconst RULE_RUST_OPENSSL_EC: RuleMeta = {\n id: \"rust-openssl-ec\",\n title: \"Rust openssl EC key generation\",\n description: \"openssl crate EcKey::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 via the Rust `openssl` crate. 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_RUST_OPENSSL_DSA: RuleMeta = {\n id: \"rust-openssl-dsa\",\n title: \"Rust openssl DSA key/usage\",\n description: \"openssl crate Dsa::generate\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"DSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Classical DSA via the Rust `openssl` crate is deprecated and forgeable by a quantum attacker.\",\n remediation: \"Rotate off DSA and migrate to ML-DSA-65 (FIPS 204).\",\n};\nconst RULE_RUST_OPENSSL_DH: RuleMeta = {\n id: \"rust-openssl-dh\",\n title: \"Rust openssl Diffie-Hellman key exchange\",\n description: \"openssl crate Dh params / key generation\",\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 via the Rust `openssl` crate is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_RUST_RING_X25519: RuleMeta = {\n id: \"rust-ring-x25519\",\n title: \"Rust ring X25519 key agreement\",\n description: \"ring agreement::X25519\",\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 key agreement via ring (Rust) is modern but still classical — harvest-now-decrypt-later.\",\n};\nconst RULE_RUST_BARE_X25519: RuleMeta = {\n id: \"rust-x25519-bare\",\n title: \"Rust X25519 key agreement (unqualified)\",\n description: \"bare EphemeralSecret::new (x25519-dalek imported via `use`)\",\n category: \"key-exchange\",\n severity: \"medium\",\n confidence: \"medium\",\n algorithm: \"X25519\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"X25519 key agreement (x25519-dalek, imported unqualified) is modern but still classical — harvest-now-decrypt-later.\",\n};\nconst RULE_RUST_BARE_SIGNINGKEY: RuleMeta = {\n id: \"rust-signingkey-bare\",\n title: \"Rust signature key (unqualified)\",\n description: \"bare SigningKey::generate/random (ed25519-dalek / k256 via `use`)\",\n category: \"signature\",\n severity: \"medium\",\n confidence: \"medium\",\n algorithm: \"unknown\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Classical signature key from an unqualified `SigningKey` (ed25519-dalek Ed25519 / k256 ECDSA) — forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_RUST_JWT_ALGORITHM: RuleMeta = {\n id: \"rust-jwt-algorithm\",\n title: \"Rust jsonwebtoken classical signature algorithm\",\n description: \"jsonwebtoken Algorithm::{RS,PS,ES}* / Algorithm::EdDSA enum variant\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n // Representative family; refined per-finding (RS*/PS* → RSA, ES* → ECDSA, EdDSA).\n algorithm: \"RSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Selects a classical JWT signature algorithm (jsonwebtoken RS*/PS*/ES*/EdDSA), forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_RUST_TLS_ACCEPT_INVALID: RuleMeta = {\n id: \"rust-tls-accept-invalid-certs\",\n title: \"Rust TLS certificate verification disabled\",\n description: \"reqwest danger_accept_invalid_certs(true)\",\n category: \"tls\",\n severity: \"high\",\n confidence: \"high\",\n hndl: false,\n cwe: CWE_CERT_VALIDATION,\n message:\n \"danger_accept_invalid_certs(true) disables TLS certificate verification in reqwest (MITM risk).\",\n remediation: \"Remove danger_accept_invalid_certs(true); verify certificates properly.\",\n};\nconst RULE_RUST_TLS_DANGEROUS: RuleMeta = {\n id: \"rust-tls-rustls-dangerous\",\n title: \"Rust rustls dangerous certificate config\",\n description: \"rustls ClientConfig .dangerous() escape hatch\",\n category: \"tls\",\n severity: \"high\",\n confidence: \"medium\",\n hndl: false,\n cwe: CWE_CERT_VALIDATION,\n message: \"rustls `.dangerous()` opts into disabling certificate verification (MITM risk).\",\n remediation: \"Avoid the dangerous() escape hatch; keep the default certificate verifier.\",\n};\n\n/** Detects classical asymmetric crypto in Rust (rsa, ring, dalek, p256/k256). */\nexport const rustDetector: Detector = {\n id: \"rust-crypto\",\n description: \"Classical asymmetric crypto in Rust (rsa, ring, *-dalek, p256/k256)\",\n scope: \"source\",\n language: \"rust\",\n rules: [\n RULE_RUST_RSA,\n RULE_RUST_ECDSA,\n RULE_RUST_ECDH,\n RULE_RUST_ED25519,\n RULE_RUST_X25519,\n RULE_RUST_OPENSSL_RSA,\n RULE_RUST_OPENSSL_EC,\n RULE_RUST_OPENSSL_DSA,\n RULE_RUST_OPENSSL_DH,\n RULE_RUST_RING_X25519,\n RULE_RUST_BARE_X25519,\n RULE_RUST_BARE_SIGNINGKEY,\n RULE_RUST_JWT_ALGORITHM,\n RULE_RUST_TLS_ACCEPT_INVALID,\n RULE_RUST_TLS_DANGEROUS,\n ],\n appliesTo: (f) => hasExtension(f, RUST_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 add(RE_RUST_RSA, RULE_RUST_RSA);\n add(RE_RUST_ECDSA, RULE_RUST_ECDSA);\n add(RE_RUST_ECDH, RULE_RUST_ECDH);\n add(RE_RUST_ED25519, RULE_RUST_ED25519);\n add(RE_RUST_X25519, RULE_RUST_X25519);\n add(RE_RUST_OPENSSL_RSA, RULE_RUST_OPENSSL_RSA);\n add(RE_RUST_OPENSSL_EC, RULE_RUST_OPENSSL_EC);\n add(RE_RUST_OPENSSL_DSA, RULE_RUST_OPENSSL_DSA);\n add(RE_RUST_OPENSSL_DH, RULE_RUST_OPENSSL_DH);\n add(RE_RUST_RING_X25519, RULE_RUST_RING_X25519);\n add(RE_RUST_BARE_X25519, RULE_RUST_BARE_X25519);\n add(RE_RUST_BARE_SIGNINGKEY, RULE_RUST_BARE_SIGNINGKEY);\n // jsonwebtoken Algorithm enum variants — resolve the family per match: the\n // RS*/PS* variants are RSASSA (RSA), ES* is ECDSA, EdDSA is Ed25519.\n eachMatch(RE_RUST_JWT_ALG, content, (m) => {\n const prefix = m[1];\n const algorithm: AlgorithmFamily =\n prefix === undefined ? \"EdDSA\" : prefix === \"ES\" ? \"ECDSA\" : \"RSA\";\n findings.push(\n findingFromRule(\n RULE_RUST_JWT_ALGORITHM,\n { file, content, index: m.index, matchLength: m[0].length },\n { algorithm },\n ),\n );\n });\n add(RE_RUST_TLS_ACCEPT_INVALID, RULE_RUST_TLS_ACCEPT_INVALID);\n add(RE_RUST_TLS_DANGEROUS, RULE_RUST_TLS_DANGEROUS);\n return findings;\n },\n};\n"]}
1
+ {"version":3,"file":"rust.js","sourceRoot":"","sources":["../../src/detectors/rust.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Source-code detector for classical asymmetric cryptography in Rust. Covers the\n * common crypto crates: `rsa`, `ring`, the `*-dalek` family (ed25519/x25519),\n * the RustCrypto elliptic-curve crates (`p256`/`p384`/`k256`), and the `openssl`\n * crate bindings. Lexical, same strategy as the other packs; the `::` path\n * syntax makes the signals precise.\n *\n * HNDL: RSA encryption and (EC/X)DH key agreement are harvest-now-decrypt-later\n * exposed (hndl:true); ECDSA / DSA / Ed25519 signatures are hndl:false but\n * forgeable. `openssl::EcKey` keygen is ambiguous (feeds ECDSA + ECDH),\n * classified conservatively as key-exchange-capable (hndl:true). Also flags\n * Rust TLS certificate-validation bypasses (reqwest / rustls) — not quantum but\n * mirrors the JS tlsDetector's cert-validation category.\n */\nimport type { AlgorithmFamily, Detector, Finding, RuleMeta } from \"../types.js\";\nimport { RUST_EXTENSIONS, eachMatch, findingFromRule, hasExtension } from \"../detect-utils.js\";\nimport { CWE_BROKEN_CRYPTO, CWE_CERT_VALIDATION } from \"../cwe.js\";\n\n// `rsa` crate + ring RsaKeyPair. `::` after the type marks an associated-fn call.\nconst RE_RUST_RSA = /\\b(?:RsaPrivateKey|RsaPublicKey|RsaKeyPair)::/g;\n// ECDSA: RustCrypto `p256::ecdsa::SigningKey` (contains `ecdsa::SigningKey`),\n// ring `EcdsaKeyPair::`, or a bare `ecdsa::SigningKey`.\nconst RE_RUST_ECDSA = /\\becdsa::SigningKey\\b|\\bEcdsaKeyPair::/g;\n// ECDH: RustCrypto `p256::ecdh::EphemeralSecret`, ring agreement / ECDH_P*.\nconst RE_RUST_ECDH = /\\becdh::EphemeralSecret\\b|\\bagreement::ECDH_P(?:256|384)\\b/g;\n// Ed25519 signatures (dalek + ring).\nconst RE_RUST_ED25519 = /\\bed25519_dalek::(?:SigningKey|Keypair|SecretKey)\\b|\\bEd25519KeyPair::/g;\n// X25519 key agreement (dalek).\nconst RE_RUST_X25519 = /\\bx25519_dalek::(?:EphemeralSecret|StaticSecret)\\b/g;\n// X448 key agreement (`x448` crate). The qualified `x448::Secret` path — covers the\n// plain `use x448::Secret;` / fully-qualified form the alias mechanism (which only\n// fires on a RENAMED `use … as`) misses.\nconst RE_RUST_X448 = /\\bx448::Secret\\b/g;\n// openssl crate bindings — the `Type::generate(` / `Dh::` call forms, distinct\n// from the ring / RustCrypto path syntax above (audit F5/F9 false-negatives).\nconst RE_RUST_OPENSSL_RSA = /\\bRsa::generate\\s*\\(/g;\nconst RE_RUST_OPENSSL_EC = /\\bEcKey::generate\\s*\\(/g;\nconst RE_RUST_OPENSSL_DSA = /\\bDsa::generate\\s*\\(/g;\nconst RE_RUST_OPENSSL_DH = /\\bDh::/g;\n// ring X25519 agreement (the ECDH_P* forms are handled by RE_RUST_ECDH above).\nconst RE_RUST_RING_X25519 = /\\bagreement::X25519\\b/g;\n// Bare (unqualified) constructors: a braced `use x25519_dalek::{EphemeralSecret}`\n// / `use ed25519_dalek::{SigningKey}` strips the `::` path prefix, defeating the\n// path-qualified rules above. The `(?<![:\\w])` lookbehind keeps these from\n// double-matching the qualified forms (e.g. `p256::ecdsa::SigningKey::random`).\nconst RE_RUST_BARE_X25519 = /(?<![:\\w])EphemeralSecret::new\\s*\\(/g;\nconst RE_RUST_BARE_SIGNINGKEY = /(?<![:\\w])SigningKey::(?:generate|random)\\s*\\(/g;\n// jsonwebtoken crate `Algorithm` enum variants selecting a classical JWT signer:\n// RSASSA-PKCS1 (RS*), RSASSA-PSS (PS*), ECDSA (ES*), and Ed25519 (EdDSA). The\n// `\\s*` between `Algorithm` and `::` catches the variant split across lines /\n// routed through a helper (audit token_policy false-negative); the required\n// suffix keeps it off unrelated `Algorithm::` uses (e.g. `HS256` HMAC, which is\n// symmetric and not quantum-vulnerable, or `Algorithm::new`).\nconst RE_RUST_JWT_ALG = /\\bAlgorithm\\s*::(RS|PS|ES)(?:256|384|512)\\b|\\bAlgorithm\\s*::EdDSA\\b/g;\n// Rust TLS certificate-validation bypass: reqwest `danger_accept_invalid_certs`\n// and the rustls `.dangerous()` escape hatch. Mirrors the JS tlsDetector.\nconst RE_RUST_TLS_ACCEPT_INVALID = /\\bdanger_accept_invalid_certs\\s*\\(\\s*true/g;\nconst RE_RUST_TLS_DANGEROUS = /\\.dangerous\\s*\\(\\s*\\)/g;\n\nconst RULE_RUST_RSA: RuleMeta = {\n id: \"rust-rsa\",\n title: \"Rust RSA key/usage\",\n description: \"the `rsa` crate / ring RsaKeyPair\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical RSA (Rust) is not quantum-safe and RSA encryption is HNDL-exposed.\",\n};\nconst RULE_RUST_ECDSA: RuleMeta = {\n id: \"rust-ecdsa\",\n title: \"Rust ECDSA signature\",\n description: \"p256/p384/k256 ecdsa::SigningKey / ring EcdsaKeyPair\",\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 (Rust) is forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_RUST_ECDH: RuleMeta = {\n id: \"rust-ecdh\",\n title: \"Rust ECDH key agreement\",\n description: \"p256/p384 ecdh::EphemeralSecret / ring agreement\",\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 (Rust) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_RUST_ED25519: RuleMeta = {\n id: \"rust-ed25519\",\n title: \"Rust Ed25519 signature\",\n description: \"ed25519-dalek SigningKey/Keypair / ring Ed25519KeyPair\",\n category: \"signature\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"EdDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Ed25519 (Rust) is a modern but still classical signature scheme.\",\n};\nconst RULE_RUST_X25519: RuleMeta = {\n id: \"rust-x25519\",\n title: \"Rust X25519 key agreement\",\n description: \"x25519-dalek EphemeralSecret/StaticSecret\",\n category: \"key-exchange\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"X25519\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"X25519 (Rust) is modern but still classical key agreement — harvest-now-decrypt-later.\",\n};\nconst RULE_RUST_X448: RuleMeta = {\n id: \"rust-x448\",\n title: \"Rust X448 key agreement\",\n description: \"the `x448` crate Secret key agreement\",\n category: \"key-exchange\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"X448\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"X448 (Rust) is modern but still classical key agreement — harvest-now-decrypt-later.\",\n};\nconst RULE_RUST_OPENSSL_RSA: RuleMeta = {\n id: \"rust-openssl-rsa\",\n title: \"Rust openssl RSA key generation\",\n description: \"openssl crate Rsa::generate\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Generates a classical RSA key pair via the Rust `openssl` crate — not quantum-safe and RSA encryption is HNDL-exposed.\",\n};\nconst RULE_RUST_OPENSSL_EC: RuleMeta = {\n id: \"rust-openssl-ec\",\n title: \"Rust openssl EC key generation\",\n description: \"openssl crate EcKey::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 via the Rust `openssl` crate. 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_RUST_OPENSSL_DSA: RuleMeta = {\n id: \"rust-openssl-dsa\",\n title: \"Rust openssl DSA key/usage\",\n description: \"openssl crate Dsa::generate\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"DSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Classical DSA via the Rust `openssl` crate is deprecated and forgeable by a quantum attacker.\",\n remediation: \"Rotate off DSA and migrate to ML-DSA-65 (FIPS 204).\",\n};\nconst RULE_RUST_OPENSSL_DH: RuleMeta = {\n id: \"rust-openssl-dh\",\n title: \"Rust openssl Diffie-Hellman key exchange\",\n description: \"openssl crate Dh params / key generation\",\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 via the Rust `openssl` crate is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_RUST_RING_X25519: RuleMeta = {\n id: \"rust-ring-x25519\",\n title: \"Rust ring X25519 key agreement\",\n description: \"ring agreement::X25519\",\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 key agreement via ring (Rust) is modern but still classical — harvest-now-decrypt-later.\",\n};\nconst RULE_RUST_BARE_X25519: RuleMeta = {\n id: \"rust-x25519-bare\",\n title: \"Rust X25519 key agreement (unqualified)\",\n description: \"bare EphemeralSecret::new (x25519-dalek imported via `use`)\",\n category: \"key-exchange\",\n severity: \"medium\",\n confidence: \"medium\",\n algorithm: \"X25519\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"X25519 key agreement (x25519-dalek, imported unqualified) is modern but still classical — harvest-now-decrypt-later.\",\n};\nconst RULE_RUST_BARE_SIGNINGKEY: RuleMeta = {\n id: \"rust-signingkey-bare\",\n title: \"Rust signature key (unqualified)\",\n description: \"bare SigningKey::generate/random (ed25519-dalek / k256 via `use`)\",\n category: \"signature\",\n severity: \"medium\",\n confidence: \"medium\",\n algorithm: \"unknown\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Classical signature key from an unqualified `SigningKey` (ed25519-dalek Ed25519 / k256 ECDSA) — forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_RUST_JWT_ALGORITHM: RuleMeta = {\n id: \"rust-jwt-algorithm\",\n title: \"Rust jsonwebtoken classical signature algorithm\",\n description: \"jsonwebtoken Algorithm::{RS,PS,ES}* / Algorithm::EdDSA enum variant\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n // Representative family; refined per-finding (RS*/PS* → RSA, ES* → ECDSA, EdDSA).\n algorithm: \"RSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Selects a classical JWT signature algorithm (jsonwebtoken RS*/PS*/ES*/EdDSA), forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_RUST_TLS_ACCEPT_INVALID: RuleMeta = {\n id: \"rust-tls-accept-invalid-certs\",\n title: \"Rust TLS certificate verification disabled\",\n description: \"reqwest danger_accept_invalid_certs(true)\",\n category: \"tls\",\n severity: \"high\",\n confidence: \"high\",\n hndl: false,\n cwe: CWE_CERT_VALIDATION,\n message:\n \"danger_accept_invalid_certs(true) disables TLS certificate verification in reqwest (MITM risk).\",\n remediation: \"Remove danger_accept_invalid_certs(true); verify certificates properly.\",\n};\nconst RULE_RUST_TLS_DANGEROUS: RuleMeta = {\n id: \"rust-tls-rustls-dangerous\",\n title: \"Rust rustls dangerous certificate config\",\n description: \"rustls ClientConfig .dangerous() escape hatch\",\n category: \"tls\",\n severity: \"high\",\n confidence: \"medium\",\n hndl: false,\n cwe: CWE_CERT_VALIDATION,\n message: \"rustls `.dangerous()` opts into disabling certificate verification (MITM risk).\",\n remediation: \"Avoid the dangerous() escape hatch; keep the default certificate verifier.\",\n};\n\n/**\n * Aliasable Rust crypto types (`<crate>::<OrigType>` → rule). A renamed `use`\n * (`use x25519_dalek::{EphemeralSecret as MontgomerySecret}`) binds the alias to a\n * classical-key type; a later `MontgomerySecret::<ctor>(` is that key's\n * construction. The `::`-qualified and braced rules above miss this because the\n * call site uses the renamed identifier, not the original path.\n */\nconst RUST_ALIASABLE: Record<string, RuleMeta> = {\n \"x25519_dalek::EphemeralSecret\": RULE_RUST_X25519,\n \"x25519_dalek::StaticSecret\": RULE_RUST_X25519,\n \"x448::Secret\": RULE_RUST_X448,\n \"ed25519_dalek::SigningKey\": RULE_RUST_ED25519,\n \"ed25519_dalek::Keypair\": RULE_RUST_ED25519,\n \"ed25519_dalek::SecretKey\": RULE_RUST_ED25519,\n};\n\n/** Escape a string for interpolation into a dynamically-built RegExp. */\nfunction escapeRustRe(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Collect `use <crate>::<OrigType> as <Alias>` bindings (braced or single) that\n * rename an aliasable crypto type, returning {alias, rule} pairs. An alias equal\n * to its own type name is skipped (the qualified/bare rules already catch it).\n */\nfunction collectRustTypeAliases(content: string): Array<{ alias: string; rule: RuleMeta }> {\n const out: Array<{ alias: string; rule: RuleMeta }> = [];\n const push = (crate: string, orig: string, alias: string): void => {\n if (!alias || alias === orig) return;\n const rule = RUST_ALIASABLE[`${crate}::${orig}`];\n if (rule) out.push({ alias, rule });\n };\n // Braced: `use <crate>::{ Orig as Alias, ... }`.\n const braced = /\\buse\\s+([\\w:]+)::\\{([^}]*)\\}/g;\n for (let m = braced.exec(content); m; m = braced.exec(content)) {\n const specRe = /([A-Za-z_]\\w*)\\s+as\\s+([A-Za-z_]\\w*)/g;\n for (let s = specRe.exec(m[2]); s; s = specRe.exec(m[2])) push(m[1], s[1], s[2]);\n }\n // Single: `use <crate>::Orig as Alias;`.\n const single = /\\buse\\s+([\\w:]+)::([A-Za-z_]\\w*)\\s+as\\s+([A-Za-z_]\\w*)/g;\n for (let m = single.exec(content); m; m = single.exec(content)) push(m[1], m[2], m[3]);\n return out;\n}\n\n/** Detects classical asymmetric crypto in Rust (rsa, ring, dalek, p256/k256). */\nexport const rustDetector: Detector = {\n id: \"rust-crypto\",\n description: \"Classical asymmetric crypto in Rust (rsa, ring, *-dalek, p256/k256)\",\n scope: \"source\",\n language: \"rust\",\n rules: [\n RULE_RUST_RSA,\n RULE_RUST_ECDSA,\n RULE_RUST_ECDH,\n RULE_RUST_ED25519,\n RULE_RUST_X25519,\n RULE_RUST_X448,\n RULE_RUST_OPENSSL_RSA,\n RULE_RUST_OPENSSL_EC,\n RULE_RUST_OPENSSL_DSA,\n RULE_RUST_OPENSSL_DH,\n RULE_RUST_RING_X25519,\n RULE_RUST_BARE_X25519,\n RULE_RUST_BARE_SIGNINGKEY,\n RULE_RUST_JWT_ALGORITHM,\n RULE_RUST_TLS_ACCEPT_INVALID,\n RULE_RUST_TLS_DANGEROUS,\n ],\n appliesTo: (f) => hasExtension(f, RUST_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 add(RE_RUST_RSA, RULE_RUST_RSA);\n add(RE_RUST_ECDSA, RULE_RUST_ECDSA);\n add(RE_RUST_ECDH, RULE_RUST_ECDH);\n add(RE_RUST_ED25519, RULE_RUST_ED25519);\n add(RE_RUST_X25519, RULE_RUST_X25519);\n add(RE_RUST_X448, RULE_RUST_X448);\n add(RE_RUST_OPENSSL_RSA, RULE_RUST_OPENSSL_RSA);\n add(RE_RUST_OPENSSL_EC, RULE_RUST_OPENSSL_EC);\n add(RE_RUST_OPENSSL_DSA, RULE_RUST_OPENSSL_DSA);\n add(RE_RUST_OPENSSL_DH, RULE_RUST_OPENSSL_DH);\n add(RE_RUST_RING_X25519, RULE_RUST_RING_X25519);\n add(RE_RUST_BARE_X25519, RULE_RUST_BARE_X25519);\n add(RE_RUST_BARE_SIGNINGKEY, RULE_RUST_BARE_SIGNINGKEY);\n // jsonwebtoken Algorithm enum variants — resolve the family per match: the\n // RS*/PS* variants are RSASSA (RSA), ES* is ECDSA, EdDSA is Ed25519.\n eachMatch(RE_RUST_JWT_ALG, content, (m) => {\n const prefix = m[1];\n const algorithm: AlgorithmFamily =\n prefix === undefined ? \"EdDSA\" : prefix === \"ES\" ? \"ECDSA\" : \"RSA\";\n findings.push(\n findingFromRule(\n RULE_RUST_JWT_ALGORITHM,\n { file, content, index: m.index, matchLength: m[0].length },\n { algorithm },\n ),\n );\n });\n add(RE_RUST_TLS_ACCEPT_INVALID, RULE_RUST_TLS_ACCEPT_INVALID);\n add(RE_RUST_TLS_DANGEROUS, RULE_RUST_TLS_DANGEROUS);\n\n // Type-alias resolution: `use x25519_dalek::{EphemeralSecret as MontgomerySecret}`\n // then `MontgomerySecret::random_from_rng(` — the braced+renamed `use` defeats\n // the `::`-qualified rules. Match the aliased type's construction calls; runs\n // on the ORIGINAL content so locations stay exact, and fires only for an alias\n // explicitly bound to a known crypto type (precision-safe).\n for (const { alias, rule } of collectRustTypeAliases(content)) {\n const a = escapeRustRe(alias);\n add(\n new RegExp(`\\\\b${a}::(?:new|random|random_from_rng|generate|from_bytes)\\\\s*\\\\(`, \"g\"),\n rule,\n );\n }\n return findings;\n },\n};\n"]}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Config detector: secrets encrypted at rest with classical asymmetric key
3
+ * wrapping. This is the purest "harvest now, decrypt later" surface — the
4
+ * ciphertext is often committed to a git repository, which means it is already
5
+ * replicated, effectively immortal, and retroactively un-fixable (you can
6
+ * re-encrypt HEAD, not history). Every recipient key here is classical.
7
+ *
8
+ * Covered:
9
+ * - Mozilla SOPS / age recipients: `age1…` bech32 public keys (X25519 key
10
+ * agreement wrapping the data key).
11
+ * - Bitnami Sealed Secrets: `kind: SealedSecret` (controller wraps with RSA-OAEP).
12
+ *
13
+ * Armored PGP blocks (`-----BEGIN PGP MESSAGE-----` and PGP private keys) are owned
14
+ * by the PEM detector (`pem-pgp-message` / `pem-pgp-private-key`), so they are not
15
+ * duplicated here.
16
+ *
17
+ * Symmetric-only schemes (ansible-vault AES, age with a scrypt passphrase) are
18
+ * intentionally NOT flagged: a strong symmetric key is only Grover-weakened, not
19
+ * broken, so it is out of scope for a *classical-asymmetric* readiness signal.
20
+ */
21
+ import type { Detector } from "../types.js";
22
+ /** Detects secrets encrypted at rest with classical asymmetric key wrapping. */
23
+ export declare const secretsDetector: Detector;
24
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/detectors/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;AAuD/D,gFAAgF;AAChF,eAAO,MAAM,eAAe,EAAE,QA0B7B,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { DOC_EXTENSIONS, eachMatch, findingFromRule, hasExtension, maskCommentLines, } from "../detect-utils.js";
2
+ import { CWE_BROKEN_CRYPTO } from "../cwe.js";
3
+ const SECRET_RULES = [
4
+ {
5
+ // age/SOPS recipient: `age1` + 58 bech32 chars. Distinctive enough for any file.
6
+ re: /\bage1[0-9a-z]{58}\b/g,
7
+ meta: {
8
+ id: "secrets-age-recipient",
9
+ title: "age / SOPS recipient (X25519)",
10
+ description: "An age (SOPS) recipient public key wraps secrets with classical X25519",
11
+ category: "key-exchange",
12
+ severity: "high",
13
+ confidence: "high",
14
+ algorithm: "X25519",
15
+ hndl: true,
16
+ cwe: CWE_BROKEN_CRYPTO,
17
+ message: "Secrets are wrapped to an age/SOPS X25519 recipient (classical key agreement); harvest-now-decrypt-later exposed, and if committed to git the ciphertext is retroactively un-fixable.",
18
+ remediation: "Track a post-quantum age recipient / KMS (ML-KEM) and re-encrypt; rotate any secret whose ciphertext has left your control.",
19
+ },
20
+ },
21
+ {
22
+ re: /\bkind:\s*["']?SealedSecret\b/g,
23
+ meta: {
24
+ id: "secrets-sealed-secret",
25
+ title: "Bitnami Sealed Secret (RSA-OAEP)",
26
+ description: "A SealedSecret is wrapped by the controller's classical RSA-OAEP key",
27
+ category: "kem",
28
+ severity: "high",
29
+ confidence: "high",
30
+ algorithm: "RSA",
31
+ hndl: true,
32
+ cwe: CWE_BROKEN_CRYPTO,
33
+ message: "A Bitnami SealedSecret is wrapped with the controller's classical RSA-OAEP key; harvest-now-decrypt-later exposed, and typically committed to git.",
34
+ remediation: "Plan migration as sealed-secrets adds PQC support; rotate the sealing key and secrets when it does.",
35
+ },
36
+ },
37
+ ];
38
+ /** Detects secrets encrypted at rest with classical asymmetric key wrapping. */
39
+ export const secretsDetector = {
40
+ id: "secrets-at-rest",
41
+ description: "Secrets wrapped at rest with classical asymmetric crypto (SOPS/age, PGP, Sealed Secrets)",
42
+ scope: "config",
43
+ language: "any",
44
+ rules: SECRET_RULES.map((r) => r.meta),
45
+ // Skip prose/docs: a tutorial showing an example age recipient is not a secret store.
46
+ appliesTo: (f) => !hasExtension(f, DOC_EXTENSIONS),
47
+ detect({ file, content }) {
48
+ // Fast reject: none of the distinctive markers present.
49
+ if (!content.includes("age1") && !content.includes("SealedSecret")) {
50
+ return [];
51
+ }
52
+ // A commented `# kind: SealedSecret` / `# age1…` is not an active setting.
53
+ const scan = maskCommentLines(content, ["#"]);
54
+ const findings = [];
55
+ for (const rule of SECRET_RULES) {
56
+ eachMatch(rule.re, scan, (m) => {
57
+ findings.push(findingFromRule(rule.meta, { file, content, index: m.index, matchLength: m[0].length }));
58
+ });
59
+ }
60
+ return findings;
61
+ },
62
+ };
63
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/detectors/secrets.ts"],"names":[],"mappings":"AAqBA,OAAO,EACL,cAAc,EACd,SAAS,EACT,eAAe,EACf,YAAY,EACZ,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAO9C,MAAM,YAAY,GAAiB;IACjC;QACE,iFAAiF;QACjF,EAAE,EAAE,uBAAuB;QAC3B,IAAI,EAAE;YACJ,EAAE,EAAE,uBAAuB;YAC3B,KAAK,EAAE,+BAA+B;YACtC,WAAW,EAAE,wEAAwE;YACrF,QAAQ,EAAE,cAAc;YACxB,QAAQ,EAAE,MAAM;YAChB,UAAU,EAAE,MAAM;YAClB,SAAS,EAAE,QAAQ;YACnB,IAAI,EAAE,IAAI;YACV,GAAG,EAAE,iBAAiB;YACtB,OAAO,EACL,uLAAuL;YACzL,WAAW,EACT,6HAA6H;SAChI;KACF;IACD;QACE,EAAE,EAAE,gCAAgC;QACpC,IAAI,EAAE;YACJ,EAAE,EAAE,uBAAuB;YAC3B,KAAK,EAAE,kCAAkC;YACzC,WAAW,EAAE,sEAAsE;YACnF,QAAQ,EAAE,KAAK;YACf,QAAQ,EAAE,MAAM;YAChB,UAAU,EAAE,MAAM;YAClB,SAAS,EAAE,KAAK;YAChB,IAAI,EAAE,IAAI;YACV,GAAG,EAAE,iBAAiB;YACtB,OAAO,EACL,oJAAoJ;YACtJ,WAAW,EACT,qGAAqG;SACxG;KACF;CACF,CAAC;AAEF,gFAAgF;AAChF,MAAM,CAAC,MAAM,eAAe,GAAa;IACvC,EAAE,EAAE,iBAAiB;IACrB,WAAW,EACT,0FAA0F;IAC5F,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE,KAAK;IACf,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACtC,sFAAsF;IACtF,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,cAAc,CAAC;IAClD,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE;QACtB,wDAAwD;QACxD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YACnE,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,2EAA2E;QAC3E,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YAChC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;gBAC7B,QAAQ,CAAC,IAAI,CACX,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CACxF,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC","sourcesContent":["/**\n * Config detector: secrets encrypted at rest with classical asymmetric key\n * wrapping. This is the purest \"harvest now, decrypt later\" surface — the\n * ciphertext is often committed to a git repository, which means it is already\n * replicated, effectively immortal, and retroactively un-fixable (you can\n * re-encrypt HEAD, not history). Every recipient key here is classical.\n *\n * Covered:\n * - Mozilla SOPS / age recipients: `age1…` bech32 public keys (X25519 key\n * agreement wrapping the data key).\n * - Bitnami Sealed Secrets: `kind: SealedSecret` (controller wraps with RSA-OAEP).\n *\n * Armored PGP blocks (`-----BEGIN PGP MESSAGE-----` and PGP private keys) are owned\n * by the PEM detector (`pem-pgp-message` / `pem-pgp-private-key`), so they are not\n * duplicated here.\n *\n * Symmetric-only schemes (ansible-vault AES, age with a scrypt passphrase) are\n * intentionally NOT flagged: a strong symmetric key is only Grover-weakened, not\n * broken, so it is out of scope for a *classical-asymmetric* readiness signal.\n */\nimport type { Detector, Finding, RuleMeta } from \"../types.js\";\nimport {\n DOC_EXTENSIONS,\n eachMatch,\n findingFromRule,\n hasExtension,\n maskCommentLines,\n} from \"../detect-utils.js\";\nimport { CWE_BROKEN_CRYPTO } from \"../cwe.js\";\n\ninterface SecretRule {\n re: RegExp;\n meta: RuleMeta;\n}\n\nconst SECRET_RULES: SecretRule[] = [\n {\n // age/SOPS recipient: `age1` + 58 bech32 chars. Distinctive enough for any file.\n re: /\\bage1[0-9a-z]{58}\\b/g,\n meta: {\n id: \"secrets-age-recipient\",\n title: \"age / SOPS recipient (X25519)\",\n description: \"An age (SOPS) recipient public key wraps secrets with classical X25519\",\n category: \"key-exchange\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"X25519\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Secrets are wrapped to an age/SOPS X25519 recipient (classical key agreement); harvest-now-decrypt-later exposed, and if committed to git the ciphertext is retroactively un-fixable.\",\n remediation:\n \"Track a post-quantum age recipient / KMS (ML-KEM) and re-encrypt; rotate any secret whose ciphertext has left your control.\",\n },\n },\n {\n re: /\\bkind:\\s*[\"']?SealedSecret\\b/g,\n meta: {\n id: \"secrets-sealed-secret\",\n title: \"Bitnami Sealed Secret (RSA-OAEP)\",\n description: \"A SealedSecret is wrapped by the controller's classical RSA-OAEP key\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"A Bitnami SealedSecret is wrapped with the controller's classical RSA-OAEP key; harvest-now-decrypt-later exposed, and typically committed to git.\",\n remediation:\n \"Plan migration as sealed-secrets adds PQC support; rotate the sealing key and secrets when it does.\",\n },\n },\n];\n\n/** Detects secrets encrypted at rest with classical asymmetric key wrapping. */\nexport const secretsDetector: Detector = {\n id: \"secrets-at-rest\",\n description:\n \"Secrets wrapped at rest with classical asymmetric crypto (SOPS/age, PGP, Sealed Secrets)\",\n scope: \"config\",\n language: \"any\",\n rules: SECRET_RULES.map((r) => r.meta),\n // Skip prose/docs: a tutorial showing an example age recipient is not a secret store.\n appliesTo: (f) => !hasExtension(f, DOC_EXTENSIONS),\n detect({ file, content }): Finding[] {\n // Fast reject: none of the distinctive markers present.\n if (!content.includes(\"age1\") && !content.includes(\"SealedSecret\")) {\n return [];\n }\n // A commented `# kind: SealedSecret` / `# age1…` is not an active setting.\n const scan = maskCommentLines(content, [\"#\"]);\n const findings: Finding[] = [];\n for (const rule of SECRET_RULES) {\n eachMatch(rule.re, scan, (m) => {\n findings.push(\n findingFromRule(rule.meta, { file, content, index: m.index, matchLength: m[0].length }),\n );\n });\n }\n return findings;\n },\n};\n"]}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Source detector for classical asymmetric cryptography in smart-contract /
3
+ * blockchain source languages: Solidity (`.sol`), Move (`.move`), and Cairo
4
+ * (`.cairo`). On-chain signature verification is pure classical elliptic-curve
5
+ * cryptography — secp256k1 ECDSA on the EVM, Ed25519 / secp256k1 on Sui & Aptos
6
+ * (Move), and STARK-curve ECDSA on Starknet (Cairo). A cryptographically-relevant
7
+ * quantum computer (CRQC) could forge any of these on-chain authorizations.
8
+ *
9
+ * HNDL: unlike a KEM or key-agreement finding, an on-chain signature check has no
10
+ * confidentiality to harvest — there is nothing to decrypt later — so every rule
11
+ * here is `hndl: false`. The exposure is nonetheless SEVERE: on-chain keys often
12
+ * ARE the custody of the asset (an account's authorization to move funds), so a
13
+ * forged signature is a direct loss, not a downgraded confidentiality guarantee.
14
+ * That is why the findings are `severity: high` despite `hndl: false`.
15
+ *
16
+ * There is no `secp256k1` value in {@link AlgorithmFamily}; secp256k1 usage is
17
+ * mapped to `ECDSA` (the scheme), and the specific curve is named in the message.
18
+ * The STARK-curve check is likewise `ECDSA` (ECDSA over the STARK-friendly curve).
19
+ *
20
+ * Patterns (verified against OpenZeppelin, Solady, Sui/Aptos Move, Starknet docs):
21
+ * - Solidity / EVM (secp256k1 ECDSA → `sol-ecrecover`):
22
+ * `ecrecover(` (the secp256k1 precompile), OpenZeppelin/Solady
23
+ * `ECDSA.recover(` / `ECDSA.tryRecover(`,
24
+ * `SignatureChecker.isValidSignatureNow(`, and imports of the
25
+ * `.../cryptography/ECDSA.sol` / `SignatureChecker.sol` (OZ) or Solady
26
+ * `utils/ECDSA.sol` libraries. Consolidated under one rule; each distinct
27
+ * token/import is its own finding (evidence), but they cannot double-fire on
28
+ * the same span.
29
+ * - Move / Sui & Aptos:
30
+ * `ed25519::signature_verify_strict(` / `ed25519_verify(` → EdDSA
31
+ * (`sol-ed25519`); `ecdsa_k1::secp256k1_verify(` /
32
+ * `ecdsa_k1::secp256k1_ecrecover(` → ECDSA secp256k1
33
+ * (`sol-secp256k1-verify`).
34
+ * - Cairo / Starknet:
35
+ * `check_ecdsa_signature(` (also the `ecdsa::check_ecdsa_signature(`
36
+ * qualified form) → ECDSA over the STARK curve (`cairo-ecdsa`).
37
+ *
38
+ * Comment suppression is done in-detector (Solidity/Move/Cairo all use C-style
39
+ * `//` line comments and `/* … *\/` block comments), so a commented-out
40
+ * verification call cannot fire. Offsets are preserved by the maskers, so finding
41
+ * line/column stay exact.
42
+ */
43
+ import type { Detector } from "../types.js";
44
+ /**
45
+ * Detects classical (quantum-vulnerable) on-chain signature verification in
46
+ * smart-contract source: Solidity/EVM secp256k1 ECDSA, Move Ed25519 & secp256k1,
47
+ * and Cairo/Starknet STARK-curve ECDSA.
48
+ */
49
+ export declare const solidityDetector: Detector;
50
+ //# sourceMappingURL=solidity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solidity.d.ts","sourceRoot":"","sources":["../../src/detectors/solidity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;AAqG/D;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,QA2B9B,CAAC"}
@@ -0,0 +1,108 @@
1
+ import { eachMatch, findingFromRule, hasExtension, maskBlockComments, maskCommentLines, SMART_CONTRACT_EXTENSIONS, } from "../detect-utils.js";
2
+ import { CWE_BROKEN_CRYPTO } from "../cwe.js";
3
+ // Shared remediation: no PQC on-chain signature scheme is standardized on these
4
+ // chains yet, so the actionable step today is to inventory the exposure and track
5
+ // each chain's roadmap for an alternative (quantum-safe) signature scheme.
6
+ const REMEDIATION_ONCHAIN = "No PQC on-chain signature scheme is standardized on these chains yet; inventory this on-chain " +
7
+ "signature verification now and track chain roadmaps (e.g. account abstraction enabling " +
8
+ "alternative signature schemes) for a quantum-safe migration path.";
9
+ // --- Solidity / EVM: secp256k1 ECDSA. ---
10
+ // The secp256k1 recovery precompile. `\b` before `ecrecover` keeps it off the
11
+ // Move `secp256k1_ecrecover` token (preceded by `_`, a word char → no boundary).
12
+ const RE_SOL_ECRECOVER = /\becrecover\s*\(/g;
13
+ // OpenZeppelin / Solady library calls: `ECDSA.recover(` / `ECDSA.tryRecover(`
14
+ // and `SignatureChecker.isValidSignatureNow(`.
15
+ const RE_SOL_ECDSA_LIB = /\bECDSA\.(?:recover|tryRecover)\s*\(|\bSignatureChecker\.isValidSignatureNow\s*\(/g;
16
+ // Import of the classical-signature libraries: OZ `.../cryptography/ECDSA.sol` /
17
+ // `.../cryptography/SignatureChecker.sol`, and Solady `.../utils/ECDSA.sol`.
18
+ const RE_SOL_ECDSA_IMPORT = /(?:cryptography|utils)\/(?:ECDSA|SignatureChecker)\.sol\b/g;
19
+ // --- Move / Sui & Aptos. ---
20
+ // Ed25519 verification: Aptos `ed25519::signature_verify_strict(`, Sui
21
+ // `ed25519::ed25519_verify(` (matched via the bare `ed25519_verify(` token).
22
+ const RE_MOVE_ED25519 = /\bed25519::signature_verify_strict\s*\(|\bed25519_verify\s*\(/g;
23
+ // secp256k1 ECDSA verification / recovery via the Sui `ecdsa_k1` module.
24
+ const RE_MOVE_SECP256K1 = /\becdsa_k1::secp256k1_(?:verify|ecrecover)\s*\(/g;
25
+ // --- Cairo / Starknet: STARK-curve ECDSA. ---
26
+ // `check_ecdsa_signature(` — also matches the qualified `ecdsa::check_ecdsa_signature(`
27
+ // (the preceding `:` is a non-word char, so the `\b` boundary still holds).
28
+ const RE_CAIRO_ECDSA = /\bcheck_ecdsa_signature\s*\(/g;
29
+ const RULE_SOL_ECRECOVER = {
30
+ id: "sol-ecrecover",
31
+ title: "EVM on-chain ECDSA signature verification (secp256k1)",
32
+ description: "Solidity ecrecover / OpenZeppelin-Solady ECDSA.recover / SignatureChecker (secp256k1)",
33
+ category: "signature",
34
+ severity: "high",
35
+ confidence: "high",
36
+ algorithm: "ECDSA",
37
+ hndl: false,
38
+ cwe: CWE_BROKEN_CRYPTO,
39
+ message: "On-chain ECDSA over secp256k1 (Solidity/EVM: ecrecover, OpenZeppelin/Solady ECDSA / SignatureChecker) is forgeable by a quantum attacker; on-chain keys often ARE asset custody.",
40
+ remediation: REMEDIATION_ONCHAIN,
41
+ };
42
+ const RULE_MOVE_ED25519 = {
43
+ id: "sol-ed25519",
44
+ title: "Move on-chain Ed25519 signature verification",
45
+ description: "Move (Sui/Aptos) ed25519::signature_verify_strict / ed25519_verify",
46
+ category: "signature",
47
+ severity: "high",
48
+ confidence: "high",
49
+ algorithm: "EdDSA",
50
+ hndl: false,
51
+ cwe: CWE_BROKEN_CRYPTO,
52
+ message: "On-chain Ed25519 signature verification (Move / Sui / Aptos) is classical and forgeable by a quantum attacker; on-chain keys often ARE asset custody.",
53
+ remediation: REMEDIATION_ONCHAIN,
54
+ };
55
+ const RULE_MOVE_SECP256K1 = {
56
+ id: "sol-secp256k1-verify",
57
+ title: "Move on-chain ECDSA signature verification (secp256k1)",
58
+ description: "Move (Sui) ecdsa_k1::secp256k1_verify / secp256k1_ecrecover",
59
+ category: "signature",
60
+ severity: "high",
61
+ confidence: "high",
62
+ algorithm: "ECDSA",
63
+ hndl: false,
64
+ cwe: CWE_BROKEN_CRYPTO,
65
+ message: "On-chain ECDSA over secp256k1 (Move / Sui ecdsa_k1) is forgeable by a quantum attacker; on-chain keys often ARE asset custody.",
66
+ remediation: REMEDIATION_ONCHAIN,
67
+ };
68
+ const RULE_CAIRO_ECDSA = {
69
+ id: "cairo-ecdsa",
70
+ title: "Cairo/Starknet on-chain ECDSA signature verification (STARK curve)",
71
+ description: "Cairo check_ecdsa_signature (STARK-curve ECDSA)",
72
+ category: "signature",
73
+ severity: "high",
74
+ confidence: "high",
75
+ algorithm: "ECDSA",
76
+ hndl: false,
77
+ cwe: CWE_BROKEN_CRYPTO,
78
+ message: "On-chain ECDSA over the STARK curve (Cairo/Starknet check_ecdsa_signature) is forgeable by a quantum attacker; on-chain keys often ARE asset custody.",
79
+ remediation: REMEDIATION_ONCHAIN,
80
+ };
81
+ /**
82
+ * Detects classical (quantum-vulnerable) on-chain signature verification in
83
+ * smart-contract source: Solidity/EVM secp256k1 ECDSA, Move Ed25519 & secp256k1,
84
+ * and Cairo/Starknet STARK-curve ECDSA.
85
+ */
86
+ export const solidityDetector = {
87
+ id: "solidity-crypto",
88
+ description: "Classical on-chain signature verification in smart-contract source (Solidity, Move, Cairo)",
89
+ scope: "source",
90
+ language: "solidity",
91
+ rules: [RULE_SOL_ECRECOVER, RULE_MOVE_ED25519, RULE_MOVE_SECP256K1, RULE_CAIRO_ECDSA],
92
+ appliesTo: (f) => hasExtension(f, SMART_CONTRACT_EXTENSIONS),
93
+ detect({ file, content }) {
94
+ // Mask C-style comments (line `//` + block `/* */`) so commented-out
95
+ // verification calls can't fire; the maskers preserve byte offsets.
96
+ const scan = maskCommentLines(maskBlockComments(content), ["//"]);
97
+ const findings = [];
98
+ const add = (re, rule) => eachMatch(re, scan, (m) => findings.push(findingFromRule(rule, { file, content, index: m.index, matchLength: m[0].length })));
99
+ add(RE_SOL_ECRECOVER, RULE_SOL_ECRECOVER);
100
+ add(RE_SOL_ECDSA_LIB, RULE_SOL_ECRECOVER);
101
+ add(RE_SOL_ECDSA_IMPORT, RULE_SOL_ECRECOVER);
102
+ add(RE_MOVE_ED25519, RULE_MOVE_ED25519);
103
+ add(RE_MOVE_SECP256K1, RULE_MOVE_SECP256K1);
104
+ add(RE_CAIRO_ECDSA, RULE_CAIRO_ECDSA);
105
+ return findings;
106
+ },
107
+ };
108
+ //# sourceMappingURL=solidity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solidity.js","sourceRoot":"","sources":["../../src/detectors/solidity.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Source detector for classical asymmetric cryptography in smart-contract /\n * blockchain source languages: Solidity (`.sol`), Move (`.move`), and Cairo\n * (`.cairo`). On-chain signature verification is pure classical elliptic-curve\n * cryptography — secp256k1 ECDSA on the EVM, Ed25519 / secp256k1 on Sui & Aptos\n * (Move), and STARK-curve ECDSA on Starknet (Cairo). A cryptographically-relevant\n * quantum computer (CRQC) could forge any of these on-chain authorizations.\n *\n * HNDL: unlike a KEM or key-agreement finding, an on-chain signature check has no\n * confidentiality to harvest — there is nothing to decrypt later — so every rule\n * here is `hndl: false`. The exposure is nonetheless SEVERE: on-chain keys often\n * ARE the custody of the asset (an account's authorization to move funds), so a\n * forged signature is a direct loss, not a downgraded confidentiality guarantee.\n * That is why the findings are `severity: high` despite `hndl: false`.\n *\n * There is no `secp256k1` value in {@link AlgorithmFamily}; secp256k1 usage is\n * mapped to `ECDSA` (the scheme), and the specific curve is named in the message.\n * The STARK-curve check is likewise `ECDSA` (ECDSA over the STARK-friendly curve).\n *\n * Patterns (verified against OpenZeppelin, Solady, Sui/Aptos Move, Starknet docs):\n * - Solidity / EVM (secp256k1 ECDSA → `sol-ecrecover`):\n * `ecrecover(` (the secp256k1 precompile), OpenZeppelin/Solady\n * `ECDSA.recover(` / `ECDSA.tryRecover(`,\n * `SignatureChecker.isValidSignatureNow(`, and imports of the\n * `.../cryptography/ECDSA.sol` / `SignatureChecker.sol` (OZ) or Solady\n * `utils/ECDSA.sol` libraries. Consolidated under one rule; each distinct\n * token/import is its own finding (evidence), but they cannot double-fire on\n * the same span.\n * - Move / Sui & Aptos:\n * `ed25519::signature_verify_strict(` / `ed25519_verify(` → EdDSA\n * (`sol-ed25519`); `ecdsa_k1::secp256k1_verify(` /\n * `ecdsa_k1::secp256k1_ecrecover(` → ECDSA secp256k1\n * (`sol-secp256k1-verify`).\n * - Cairo / Starknet:\n * `check_ecdsa_signature(` (also the `ecdsa::check_ecdsa_signature(`\n * qualified form) → ECDSA over the STARK curve (`cairo-ecdsa`).\n *\n * Comment suppression is done in-detector (Solidity/Move/Cairo all use C-style\n * `//` line comments and `/* … *\\/` block comments), so a commented-out\n * verification call cannot fire. Offsets are preserved by the maskers, so finding\n * line/column stay exact.\n */\nimport type { Detector, Finding, RuleMeta } from \"../types.js\";\nimport {\n eachMatch,\n findingFromRule,\n hasExtension,\n maskBlockComments,\n maskCommentLines,\n SMART_CONTRACT_EXTENSIONS,\n} from \"../detect-utils.js\";\nimport { CWE_BROKEN_CRYPTO } from \"../cwe.js\";\n\n// Shared remediation: no PQC on-chain signature scheme is standardized on these\n// chains yet, so the actionable step today is to inventory the exposure and track\n// each chain's roadmap for an alternative (quantum-safe) signature scheme.\nconst REMEDIATION_ONCHAIN =\n \"No PQC on-chain signature scheme is standardized on these chains yet; inventory this on-chain \" +\n \"signature verification now and track chain roadmaps (e.g. account abstraction enabling \" +\n \"alternative signature schemes) for a quantum-safe migration path.\";\n\n// --- Solidity / EVM: secp256k1 ECDSA. ---\n// The secp256k1 recovery precompile. `\\b` before `ecrecover` keeps it off the\n// Move `secp256k1_ecrecover` token (preceded by `_`, a word char → no boundary).\nconst RE_SOL_ECRECOVER = /\\becrecover\\s*\\(/g;\n// OpenZeppelin / Solady library calls: `ECDSA.recover(` / `ECDSA.tryRecover(`\n// and `SignatureChecker.isValidSignatureNow(`.\nconst RE_SOL_ECDSA_LIB =\n /\\bECDSA\\.(?:recover|tryRecover)\\s*\\(|\\bSignatureChecker\\.isValidSignatureNow\\s*\\(/g;\n// Import of the classical-signature libraries: OZ `.../cryptography/ECDSA.sol` /\n// `.../cryptography/SignatureChecker.sol`, and Solady `.../utils/ECDSA.sol`.\nconst RE_SOL_ECDSA_IMPORT = /(?:cryptography|utils)\\/(?:ECDSA|SignatureChecker)\\.sol\\b/g;\n\n// --- Move / Sui & Aptos. ---\n// Ed25519 verification: Aptos `ed25519::signature_verify_strict(`, Sui\n// `ed25519::ed25519_verify(` (matched via the bare `ed25519_verify(` token).\nconst RE_MOVE_ED25519 = /\\bed25519::signature_verify_strict\\s*\\(|\\bed25519_verify\\s*\\(/g;\n// secp256k1 ECDSA verification / recovery via the Sui `ecdsa_k1` module.\nconst RE_MOVE_SECP256K1 = /\\becdsa_k1::secp256k1_(?:verify|ecrecover)\\s*\\(/g;\n\n// --- Cairo / Starknet: STARK-curve ECDSA. ---\n// `check_ecdsa_signature(` — also matches the qualified `ecdsa::check_ecdsa_signature(`\n// (the preceding `:` is a non-word char, so the `\\b` boundary still holds).\nconst RE_CAIRO_ECDSA = /\\bcheck_ecdsa_signature\\s*\\(/g;\n\nconst RULE_SOL_ECRECOVER: RuleMeta = {\n id: \"sol-ecrecover\",\n title: \"EVM on-chain ECDSA signature verification (secp256k1)\",\n description:\n \"Solidity ecrecover / OpenZeppelin-Solady ECDSA.recover / SignatureChecker (secp256k1)\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"On-chain ECDSA over secp256k1 (Solidity/EVM: ecrecover, OpenZeppelin/Solady ECDSA / SignatureChecker) is forgeable by a quantum attacker; on-chain keys often ARE asset custody.\",\n remediation: REMEDIATION_ONCHAIN,\n};\nconst RULE_MOVE_ED25519: RuleMeta = {\n id: \"sol-ed25519\",\n title: \"Move on-chain Ed25519 signature verification\",\n description: \"Move (Sui/Aptos) ed25519::signature_verify_strict / ed25519_verify\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"EdDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"On-chain Ed25519 signature verification (Move / Sui / Aptos) is classical and forgeable by a quantum attacker; on-chain keys often ARE asset custody.\",\n remediation: REMEDIATION_ONCHAIN,\n};\nconst RULE_MOVE_SECP256K1: RuleMeta = {\n id: \"sol-secp256k1-verify\",\n title: \"Move on-chain ECDSA signature verification (secp256k1)\",\n description: \"Move (Sui) ecdsa_k1::secp256k1_verify / secp256k1_ecrecover\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"On-chain ECDSA over secp256k1 (Move / Sui ecdsa_k1) is forgeable by a quantum attacker; on-chain keys often ARE asset custody.\",\n remediation: REMEDIATION_ONCHAIN,\n};\nconst RULE_CAIRO_ECDSA: RuleMeta = {\n id: \"cairo-ecdsa\",\n title: \"Cairo/Starknet on-chain ECDSA signature verification (STARK curve)\",\n description: \"Cairo check_ecdsa_signature (STARK-curve ECDSA)\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"On-chain ECDSA over the STARK curve (Cairo/Starknet check_ecdsa_signature) is forgeable by a quantum attacker; on-chain keys often ARE asset custody.\",\n remediation: REMEDIATION_ONCHAIN,\n};\n\n/**\n * Detects classical (quantum-vulnerable) on-chain signature verification in\n * smart-contract source: Solidity/EVM secp256k1 ECDSA, Move Ed25519 & secp256k1,\n * and Cairo/Starknet STARK-curve ECDSA.\n */\nexport const solidityDetector: Detector = {\n id: \"solidity-crypto\",\n description:\n \"Classical on-chain signature verification in smart-contract source (Solidity, Move, Cairo)\",\n scope: \"source\",\n language: \"solidity\",\n rules: [RULE_SOL_ECRECOVER, RULE_MOVE_ED25519, RULE_MOVE_SECP256K1, RULE_CAIRO_ECDSA],\n appliesTo: (f) => hasExtension(f, SMART_CONTRACT_EXTENSIONS),\n detect({ file, content }): Finding[] {\n // Mask C-style comments (line `//` + block `/* */`) so commented-out\n // verification calls can't fire; the maskers preserve byte offsets.\n const scan = maskCommentLines(maskBlockComments(content), [\"//\"]);\n const findings: Finding[] = [];\n const add = (re: RegExp, rule: RuleMeta) =>\n eachMatch(re, scan, (m) =>\n findings.push(\n findingFromRule(rule, { file, content, index: m.index, matchLength: m[0].length }),\n ),\n );\n add(RE_SOL_ECRECOVER, RULE_SOL_ECRECOVER);\n add(RE_SOL_ECDSA_LIB, RULE_SOL_ECRECOVER);\n add(RE_SOL_ECDSA_IMPORT, RULE_SOL_ECRECOVER);\n add(RE_MOVE_ED25519, RULE_MOVE_ED25519);\n add(RE_MOVE_SECP256K1, RULE_MOVE_SECP256K1);\n add(RE_CAIRO_ECDSA, RULE_CAIRO_ECDSA);\n return findings;\n },\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/detectors/source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;AA4/B/D,0DAA0D;AAC1D,eAAO,MAAM,eAAe,EAAE,QAAQ,EAQrC,CAAC"}
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/detectors/source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;AA8sC/D,0DAA0D;AAC1D,eAAO,MAAM,eAAe,EAAE,QAAQ,EAQrC,CAAC"}