@quantakrypto/core 0.4.4 → 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.
- package/README.md +76 -27
- package/dist/cbom-merge.d.ts.map +1 -1
- package/dist/cbom-merge.js +30 -8
- package/dist/cbom-merge.js.map +1 -1
- package/dist/cbom.d.ts +5 -0
- package/dist/cbom.d.ts.map +1 -1
- package/dist/cbom.js +132 -37
- package/dist/cbom.js.map +1 -1
- package/dist/comments.d.ts +2 -23
- package/dist/comments.d.ts.map +1 -1
- package/dist/comments.js +24 -5
- package/dist/comments.js.map +1 -1
- package/dist/detect-utils.d.ts +55 -21
- package/dist/detect-utils.d.ts.map +1 -1
- package/dist/detect-utils.js +133 -7
- package/dist/detect-utils.js.map +1 -1
- package/dist/detectors/age.d.ts +16 -0
- package/dist/detectors/age.d.ts.map +1 -0
- package/dist/detectors/age.js +40 -0
- package/dist/detectors/age.js.map +1 -0
- package/dist/detectors/ansible.d.ts +13 -0
- package/dist/detectors/ansible.d.ts.map +1 -0
- package/dist/detectors/ansible.js +108 -0
- package/dist/detectors/ansible.js.map +1 -0
- package/dist/detectors/bicep.d.ts +20 -0
- package/dist/detectors/bicep.d.ts.map +1 -0
- package/dist/detectors/bicep.js +74 -0
- package/dist/detectors/bicep.js.map +1 -0
- package/dist/detectors/c.d.ts.map +1 -1
- package/dist/detectors/c.js +30 -3
- package/dist/detectors/c.js.map +1 -1
- package/dist/detectors/cicd.d.ts.map +1 -1
- package/dist/detectors/cicd.js +18 -5
- package/dist/detectors/cicd.js.map +1 -1
- package/dist/detectors/cloud-kms.d.ts +8 -5
- package/dist/detectors/cloud-kms.d.ts.map +1 -1
- package/dist/detectors/cloud-kms.js +62 -20
- package/dist/detectors/cloud-kms.js.map +1 -1
- package/dist/detectors/cloudformation.d.ts +8 -0
- package/dist/detectors/cloudformation.d.ts.map +1 -1
- package/dist/detectors/cloudformation.js +41 -10
- package/dist/detectors/cloudformation.js.map +1 -1
- package/dist/detectors/codesign.d.ts +50 -0
- package/dist/detectors/codesign.d.ts.map +1 -0
- package/dist/detectors/codesign.js +143 -0
- package/dist/detectors/codesign.js.map +1 -0
- package/dist/detectors/csharp.d.ts.map +1 -1
- package/dist/detectors/csharp.js +13 -3
- package/dist/detectors/csharp.js.map +1 -1
- package/dist/detectors/dart.d.ts +35 -0
- package/dist/detectors/dart.d.ts.map +1 -0
- package/dist/detectors/dart.js +177 -0
- package/dist/detectors/dart.js.map +1 -0
- package/dist/detectors/database.d.ts +5 -3
- package/dist/detectors/database.d.ts.map +1 -1
- package/dist/detectors/database.js +45 -8
- package/dist/detectors/database.js.map +1 -1
- package/dist/detectors/dkim.d.ts +54 -0
- package/dist/detectors/dkim.d.ts.map +1 -0
- package/dist/detectors/dkim.js +92 -0
- package/dist/detectors/dkim.js.map +1 -0
- package/dist/detectors/dnssec.d.ts.map +1 -1
- package/dist/detectors/dnssec.js +19 -10
- package/dist/detectors/dnssec.js.map +1 -1
- package/dist/detectors/elixir.d.ts.map +1 -1
- package/dist/detectors/elixir.js +34 -2
- package/dist/detectors/elixir.js.map +1 -1
- package/dist/detectors/java.d.ts.map +1 -1
- package/dist/detectors/java.js +33 -3
- package/dist/detectors/java.js.map +1 -1
- package/dist/detectors/jose.d.ts.map +1 -1
- package/dist/detectors/jose.js +13 -3
- package/dist/detectors/jose.js.map +1 -1
- package/dist/detectors/jwk.d.ts +7 -7
- package/dist/detectors/jwk.d.ts.map +1 -1
- package/dist/detectors/jwk.js +44 -8
- package/dist/detectors/jwk.js.map +1 -1
- package/dist/detectors/k8s.d.ts.map +1 -1
- package/dist/detectors/k8s.js +5 -2
- package/dist/detectors/k8s.js.map +1 -1
- package/dist/detectors/keystore.d.ts +19 -0
- package/dist/detectors/keystore.d.ts.map +1 -0
- package/dist/detectors/keystore.js +76 -0
- package/dist/detectors/keystore.js.map +1 -0
- package/dist/detectors/mesh.d.ts +7 -8
- package/dist/detectors/mesh.d.ts.map +1 -1
- package/dist/detectors/mesh.js +17 -35
- package/dist/detectors/mesh.js.map +1 -1
- package/dist/detectors/messaging.d.ts +2 -2
- package/dist/detectors/messaging.d.ts.map +1 -1
- package/dist/detectors/messaging.js +19 -12
- package/dist/detectors/messaging.js.map +1 -1
- package/dist/detectors/objc.d.ts +41 -0
- package/dist/detectors/objc.d.ts.map +1 -0
- package/dist/detectors/objc.js +146 -0
- package/dist/detectors/objc.js.map +1 -0
- package/dist/detectors/openpgp.d.ts +20 -0
- package/dist/detectors/openpgp.d.ts.map +1 -0
- package/dist/detectors/openpgp.js +151 -0
- package/dist/detectors/openpgp.js.map +1 -0
- package/dist/detectors/pem.d.ts.map +1 -1
- package/dist/detectors/pem.js +32 -0
- package/dist/detectors/pem.js.map +1 -1
- package/dist/detectors/php.d.ts +2 -1
- package/dist/detectors/php.d.ts.map +1 -1
- package/dist/detectors/php.js +7 -3
- package/dist/detectors/php.js.map +1 -1
- package/dist/detectors/pkcs11.d.ts +17 -0
- package/dist/detectors/pkcs11.d.ts.map +1 -0
- package/dist/detectors/pkcs11.js +87 -0
- package/dist/detectors/pkcs11.js.map +1 -0
- package/dist/detectors/proxy.d.ts +52 -0
- package/dist/detectors/proxy.d.ts.map +1 -0
- package/dist/detectors/proxy.js +157 -0
- package/dist/detectors/proxy.js.map +1 -0
- package/dist/detectors/pulumi.d.ts +19 -0
- package/dist/detectors/pulumi.d.ts.map +1 -0
- package/dist/detectors/pulumi.js +80 -0
- package/dist/detectors/pulumi.js.map +1 -0
- package/dist/detectors/rust.d.ts.map +1 -1
- package/dist/detectors/rust.js +5 -0
- package/dist/detectors/rust.js.map +1 -1
- package/dist/detectors/secrets.d.ts +4 -1
- package/dist/detectors/secrets.d.ts.map +1 -1
- package/dist/detectors/secrets.js +5 -21
- package/dist/detectors/secrets.js.map +1 -1
- package/dist/detectors/solidity.d.ts +50 -0
- package/dist/detectors/solidity.d.ts.map +1 -0
- package/dist/detectors/solidity.js +108 -0
- package/dist/detectors/solidity.js.map +1 -0
- package/dist/detectors/source.d.ts.map +1 -1
- package/dist/detectors/source.js +53 -6
- package/dist/detectors/source.js.map +1 -1
- package/dist/detectors/spire.d.ts +49 -0
- package/dist/detectors/spire.d.ts.map +1 -0
- package/dist/detectors/spire.js +77 -0
- package/dist/detectors/spire.js.map +1 -0
- package/dist/detectors/ssh-ca.d.ts +72 -0
- package/dist/detectors/ssh-ca.d.ts.map +1 -0
- package/dist/detectors/ssh-ca.js +119 -0
- package/dist/detectors/ssh-ca.js.map +1 -0
- package/dist/detectors/supply-chain.d.ts +17 -0
- package/dist/detectors/supply-chain.d.ts.map +1 -0
- package/dist/detectors/supply-chain.js +89 -0
- package/dist/detectors/supply-chain.js.map +1 -0
- package/dist/detectors/swift.d.ts +22 -0
- package/dist/detectors/swift.d.ts.map +1 -0
- package/dist/detectors/swift.js +120 -0
- package/dist/detectors/swift.js.map +1 -0
- package/dist/detectors/terraform.d.ts.map +1 -1
- package/dist/detectors/terraform.js +35 -8
- package/dist/detectors/terraform.js.map +1 -1
- package/dist/detectors/vault.d.ts +15 -0
- package/dist/detectors/vault.d.ts.map +1 -0
- package/dist/detectors/vault.js +97 -0
- package/dist/detectors/vault.js.map +1 -0
- package/dist/detectors/vpn.d.ts +8 -8
- package/dist/detectors/vpn.d.ts.map +1 -1
- package/dist/detectors/vpn.js +12 -38
- package/dist/detectors/vpn.js.map +1 -1
- package/dist/detectors/weak-hash.d.ts +71 -0
- package/dist/detectors/weak-hash.d.ts.map +1 -0
- package/dist/detectors/weak-hash.js +116 -0
- package/dist/detectors/weak-hash.js.map +1 -0
- package/dist/detectors/webauthn.d.ts +61 -0
- package/dist/detectors/webauthn.d.ts.map +1 -0
- package/dist/detectors/webauthn.js +109 -0
- package/dist/detectors/webauthn.js.map +1 -0
- package/dist/detectors/xmldsig.d.ts +23 -0
- package/dist/detectors/xmldsig.d.ts.map +1 -0
- package/dist/detectors/xmldsig.js +84 -0
- package/dist/detectors/xmldsig.js.map +1 -0
- package/dist/evidence.d.ts +74 -4
- package/dist/evidence.d.ts.map +1 -1
- package/dist/evidence.js +71 -0
- package/dist/evidence.js.map +1 -1
- package/dist/index.d.ts +14 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -11
- package/dist/index.js.map +1 -1
- package/dist/inventory.d.ts +0 -2
- package/dist/inventory.d.ts.map +1 -1
- package/dist/inventory.js +15 -6
- package/dist/inventory.js.map +1 -1
- package/dist/registry.d.ts +9 -4
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +51 -4
- package/dist/registry.js.map +1 -1
- package/dist/remediate-pipeline.d.ts +0 -3
- package/dist/remediate-pipeline.d.ts.map +1 -1
- package/dist/remediate-pipeline.js +1 -1
- package/dist/remediate-pipeline.js.map +1 -1
- package/dist/remediation.d.ts +10 -0
- package/dist/remediation.d.ts.map +1 -1
- package/dist/remediation.js +32 -0
- package/dist/remediation.js.map +1 -1
- package/dist/report.d.ts +9 -0
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +31 -1
- package/dist/report.js.map +1 -1
- package/dist/scan-worker.js +5 -3
- package/dist/scan-worker.js.map +1 -1
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +35 -6
- package/dist/scan.js.map +1 -1
- package/dist/standards-profiles.d.ts +58 -0
- package/dist/standards-profiles.d.ts.map +1 -0
- package/dist/standards-profiles.js +100 -0
- package/dist/standards-profiles.js.map +1 -0
- package/dist/types.d.ts +6 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/vex.d.ts +39 -0
- package/dist/vex.d.ts.map +1 -0
- package/dist/vex.js +87 -0
- package/dist/vex.js.map +1 -0
- package/dist/walk.d.ts +8 -3
- package/dist/walk.d.ts.map +1 -1
- package/dist/walk.js +32 -1
- package/dist/walk.js.map +1 -1
- package/package.json +1 -1
- package/src/cbom-merge.ts +38 -8
- package/src/cbom.ts +153 -39
- package/src/comments.ts +25 -6
- package/src/detect-utils.ts +133 -11
- package/src/detectors/age.ts +60 -0
- package/src/detectors/ansible.ts +140 -0
- package/src/detectors/bicep.ts +107 -0
- package/src/detectors/c.ts +31 -3
- package/src/detectors/cicd.ts +18 -5
- package/src/detectors/cloud-kms.ts +79 -25
- package/src/detectors/cloudformation.ts +45 -10
- package/src/detectors/codesign.ts +214 -0
- package/src/detectors/csharp.ts +13 -3
- package/src/detectors/dart.ts +237 -0
- package/src/detectors/database.ts +64 -11
- package/src/detectors/dkim.ts +172 -0
- package/src/detectors/dnssec.ts +19 -10
- package/src/detectors/elixir.ts +33 -2
- package/src/detectors/java.ts +37 -3
- package/src/detectors/jose.ts +19 -3
- package/src/detectors/jwk.ts +59 -17
- package/src/detectors/k8s.ts +5 -2
- package/src/detectors/keystore.ts +109 -0
- package/src/detectors/mesh.ts +21 -45
- package/src/detectors/messaging.ts +22 -14
- package/src/detectors/objc.ts +209 -0
- package/src/detectors/openpgp.ts +194 -0
- package/src/detectors/pem.ts +30 -0
- package/src/detectors/php.ts +9 -4
- package/src/detectors/pkcs11.ts +113 -0
- package/src/detectors/proxy.ts +236 -0
- package/src/detectors/pulumi.ts +106 -0
- package/src/detectors/rust.ts +5 -0
- package/src/detectors/secrets.ts +15 -26
- package/src/detectors/solidity.ts +176 -0
- package/src/detectors/source.ts +48 -5
- package/src/detectors/spire.ts +143 -0
- package/src/detectors/ssh-ca.ts +215 -0
- package/src/detectors/supply-chain.ts +117 -0
- package/src/detectors/swift.ts +149 -0
- package/src/detectors/terraform.ts +42 -8
- package/src/detectors/vault.ts +120 -0
- package/src/detectors/vpn.ts +20 -48
- package/src/detectors/weak-hash.ts +217 -0
- package/src/detectors/webauthn.ts +205 -0
- package/src/detectors/xmldsig.ts +115 -0
- package/src/evidence.ts +127 -4
- package/src/index.ts +41 -13
- package/src/inventory.ts +15 -7
- package/src/registry.ts +51 -4
- package/src/remediate-pipeline.ts +1 -1
- package/src/remediation.ts +39 -0
- package/src/report.ts +36 -1
- package/src/scan-worker.ts +5 -3
- package/src/scan.ts +41 -6
- package/src/standards-profiles.ts +136 -0
- package/src/types.ts +9 -4
- package/src/version.ts +1 -1
- package/src/vex.ts +122 -0
- package/src/walk.ts +33 -2
package/dist/detectors/c.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"c.js","sourceRoot":"","sources":["../../src/detectors/c.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Source-code detector for classical asymmetric cryptography in C / C++ using\n * OpenSSL (the dominant crypto library for the ecosystem), libsodium, and — for\n * the embedded / firmware / IoT niche — Mbed TLS (`mbedtls_*`) and wolfSSL /\n * wolfCrypt (`wc_*`). Lexical, same strategy as the other packs; every library's\n * function names are distinctive enough to keep the false-positive risk low.\n *\n * NOTE: scanning OpenSSL's OWN source/headers will naturally light up (the\n * library declares these symbols) — that is inherent to lexical scanning of a\n * crypto library, not a false positive in application code. Matches the classic\n * `*_generate_key` / `ECDSA_sign` / `ECDH_compute_key` call forms plus the\n * `EVP_RSA_gen` helper.\n *\n * HNDL: RSA encryption and (EC)DH key agreement are harvest-now-decrypt-later\n * exposed (hndl:true); ECDSA / DSA signatures are hndl:false but forgeable.\n * `EC_KEY_generate_key` is ambiguous (feeds ECDSA + ECDH), classified\n * conservatively as key-exchange-capable (hndl:true).\n */\nimport type { Detector, Finding, RuleMeta } from \"../types.js\";\nimport { C_EXTENSIONS, eachMatch, findingFromRule, hasExtension } from \"../detect-utils.js\";\nimport { CWE_BROKEN_CRYPTO, CWE_CERT_VALIDATION, CWE_WEAK_STRENGTH } from \"../cwe.js\";\n\nconst RE_C_RSA = /\\bRSA_generate_key(?:_ex)?\\s*\\(|\\bEVP_RSA_gen\\s*\\(/g;\nconst RE_C_EC = /\\bEC_KEY_generate_key\\s*\\(|\\bEC_KEY_new_by_curve_name\\s*\\(/g;\nconst RE_C_ECDSA = /\\bECDSA_do_sign\\s*\\(|\\bECDSA_sign\\s*\\(/g;\nconst RE_C_ECDH = /\\bECDH_compute_key\\s*\\(/g;\nconst RE_C_DSA = /\\bDSA_generate_key\\s*\\(|\\bDSA_generate_parameters(?:_ex)?\\s*\\(/g;\nconst RE_C_DH = /\\bDH_generate_key\\s*\\(|\\bDH_generate_parameters(?:_ex)?\\s*\\(/g;\n// Modern OpenSSL 3.x EVP API (the legacy *_generate_key forms above are\n// deprecated) + libsodium — the biggest C false-negative surface (audit F1).\nconst RE_C_EVP_KEYGEN = /\\bEVP_PKEY_(?:Q_)?keygen\\s*\\(|\\bEVP_PKEY_paramgen\\s*\\(/g;\nconst RE_C_EVP_DERIVE = /\\bEVP_PKEY_derive\\s*\\(/g;\nconst RE_C_EVP_CRYPT = /\\bEVP_PKEY_(?:encrypt|decrypt)\\s*\\(/g;\nconst RE_C_EVP_SIGN = /\\bEVP_DigestSign(?:Init)?\\s*\\(|\\bEVP_DigestVerify(?:Init)?\\s*\\(/g;\n// X25519: crypto_box / crypto_kx key pairs (incl. the fully-qualified\n// curve25519xsalsa20poly1305 form) plus the low-level crypto_scalarmult\n// primitive — all classical Curve25519 key agreement (audit recall gap).\nconst RE_C_SODIUM_BOX =\n /\\bcrypto_box_(?:curve25519xsalsa20poly1305_)?(?:seed_)?keypair\\s*\\(|\\bcrypto_kx_keypair\\s*\\(|\\bcrypto_scalarmult_(?:curve25519|base)\\s*\\(/g;\n// EdDSA: crypto_sign key pairs, including the explicit _ed25519 forms and the\n// deterministic seed_keypair variants (audit recall gap: _ed25519_keypair).\nconst RE_C_SODIUM_SIGN = /\\bcrypto_sign_(?:ed25519_)?(?:seed_)?keypair\\s*\\(/g;\n// Legacy verify / decrypt counterparts to the *_sign / *_encrypt rules above\n// (audit F4-c): the classic OpenSSL RSA/ECDSA verification and RSA raw\n// decryption call forms that the modern EVP + legacy keygen rules don't cover.\nconst RE_C_ECDSA_VERIFY = /\\bECDSA_verify\\s*\\(/g;\nconst RE_C_RSA_VERIFY = /\\bRSA_verify\\s*\\(/g;\nconst RE_C_RSA_CRYPT = /\\bRSA_public_encrypt\\s*\\(|\\bRSA_private_decrypt\\s*\\(/g;\n// C/OpenSSL legacy TLS configuration (mirrors source.ts tlsDetector): forcing a\n// deprecated protocol version or disabling certificate verification.\nconst RE_C_TLS_VERSION = /\\bTLSv1_method\\b|\\bSSLv3_method\\b/g;\nconst RE_C_TLS_VERIFY_NONE = /\\bSSL_VERIFY_NONE\\b/g;\n// Embedded C crypto libraries (the \"embedded\" niche): Mbed TLS and wolfSSL /\n// wolfCrypt. Both use highly-distinctive `mbedtls_*` / `wc_*` prefixes, so the\n// false-positive risk is low. These dominate firmware / IoT / RTOS builds where\n// OpenSSL is too heavy — a codebase surface qScan previously missed entirely.\nconst RE_C_MBEDTLS_RSA = /\\bmbedtls_rsa_gen_key\\s*\\(/g;\nconst RE_C_MBEDTLS_EC = /\\bmbedtls_ecp_gen_key(?:pair)?\\s*\\(/g;\nconst RE_C_MBEDTLS_ECDSA =\n /\\bmbedtls_ecdsa_(?:sign|write_signature|read_signature|verify)\\w*\\s*\\(/g;\nconst RE_C_MBEDTLS_ECDH = /\\bmbedtls_ecdh_(?:compute_shared|calc_secret)\\s*\\(/g;\nconst RE_C_MBEDTLS_DH = /\\bmbedtls_dhm_(?:make_public|make_params|calc_secret)\\s*\\(/g;\nconst RE_C_WOLF_RSA =\n /\\bwc_MakeRsaKey\\s*\\(|\\bwc_RsaPublicEncrypt\\s*\\(|\\bwc_RsaPrivateDecrypt\\s*\\(/g;\nconst RE_C_WOLF_ECC = /\\bwc_ecc_make_key(?:_ex)?\\s*\\(/g;\nconst RE_C_WOLF_ECDSA = /\\bwc_ecc_sign_hash\\s*\\(|\\bwc_ecc_verify_hash\\s*\\(/g;\nconst RE_C_WOLF_ECDH = /\\bwc_ecc_shared_secret\\s*\\(/g;\nconst RE_C_WOLF_DH = /\\bwc_DhGenerateKeyPair\\s*\\(|\\bwc_DhAgree\\s*\\(/g;\nconst RE_C_WOLF_CURVE25519 = /\\bwc_curve25519_(?:make_key|shared_secret)\\s*\\(/g;\nconst RE_C_WOLF_ED25519 = /\\bwc_ed25519_(?:make_key|sign_msg|verify_msg)\\s*\\(/g;\n\nconst RULE_C_RSA: RuleMeta = {\n id: \"c-rsa-keygen\",\n title: \"C/OpenSSL RSA key generation\",\n description: \"OpenSSL RSA_generate_key(_ex) / EVP_RSA_gen\",\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 (C/OpenSSL), which is not quantum-safe.\",\n};\nconst RULE_C_EC: RuleMeta = {\n id: \"c-ec-keygen\",\n title: \"C/OpenSSL EC key generation\",\n description: \"OpenSSL EC_KEY_generate_key / EC_KEY_new_by_curve_name\",\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 (C/OpenSSL). 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_C_ECDSA: RuleMeta = {\n id: \"c-ecdsa\",\n title: \"C/OpenSSL ECDSA signature\",\n description: \"OpenSSL ECDSA_sign / ECDSA_do_sign\",\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 (C/OpenSSL) is forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_C_ECDH: RuleMeta = {\n id: \"c-ecdh\",\n title: \"C/OpenSSL ECDH key agreement\",\n description: \"OpenSSL ECDH_compute_key\",\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 (C/OpenSSL) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_C_DSA: RuleMeta = {\n id: \"c-dsa\",\n title: \"C/OpenSSL DSA key/usage\",\n description: \"OpenSSL DSA_generate_key / DSA_generate_parameters\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"DSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical DSA (C/OpenSSL) is deprecated and forgeable by a quantum attacker.\",\n remediation: \"Rotate off DSA and migrate to ML-DSA-65 (FIPS 204).\",\n};\nconst RULE_C_DH: RuleMeta = {\n id: \"c-dh\",\n title: \"C/OpenSSL Diffie-Hellman key exchange\",\n description: \"OpenSSL DH_generate_key / DH_generate_parameters\",\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 (C/OpenSSL) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_C_EVP_KEYGEN: RuleMeta = {\n id: \"c-evp-keygen\",\n title: \"C/OpenSSL EVP key generation\",\n description: \"OpenSSL 3.x EVP_PKEY_keygen / EVP_PKEY_Q_keygen / paramgen\",\n category: \"key-exchange\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"unknown\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Generates an asymmetric key via the OpenSSL 3.x EVP API (the key type — RSA/EC/DH/X25519 — is set on the CTX). Treated conservatively as key-exchange-capable (harvest-now-decrypt-later).\",\n remediation:\n \"For key agreement: hybrid X25519MLKEM768 (ML-KEM-768). For signatures: ML-DSA-65 (FIPS 204).\",\n};\nconst RULE_C_EVP_DERIVE: RuleMeta = {\n id: \"c-evp-derive\",\n title: \"C/OpenSSL EVP key agreement\",\n description: \"OpenSSL 3.x EVP_PKEY_derive (ECDH / DH shared secret)\",\n category: \"key-exchange\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDH\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Derives an (EC)DH shared secret via the OpenSSL EVP API — broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_C_EVP_CRYPT: RuleMeta = {\n id: \"c-evp-pkey-crypt\",\n title: \"C/OpenSSL EVP public-key encryption\",\n description: \"OpenSSL 3.x EVP_PKEY_encrypt / EVP_PKEY_decrypt (RSA)\",\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/decryption via the OpenSSL EVP API is harvest-now-decrypt-later exposed.\",\n};\nconst RULE_C_EVP_SIGN: RuleMeta = {\n id: \"c-evp-sign\",\n title: \"C/OpenSSL EVP signing\",\n description: \"OpenSSL 3.x EVP_DigestSign* / EVP_DigestVerify*\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"unknown\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Classical signature via the OpenSSL EVP API (RSA/ECDSA/EdDSA) is forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_C_SODIUM_BOX: RuleMeta = {\n id: \"c-libsodium-box\",\n title: \"libsodium X25519 key pair\",\n description:\n \"libsodium crypto_box / crypto_kx keypair + crypto_scalarmult (X25519 key agreement)\",\n category: \"key-exchange\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"X25519\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"libsodium crypto_box uses X25519 key agreement — modern but classical, and harvest-now-decrypt-later exposed.\",\n};\nconst RULE_C_SODIUM_SIGN: RuleMeta = {\n id: \"c-libsodium-sign\",\n title: \"libsodium Ed25519 key pair\",\n description: \"libsodium crypto_sign(_ed25519)(_seed)_keypair (Ed25519 signatures)\",\n category: \"signature\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"EdDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"libsodium crypto_sign uses Ed25519 signatures — classical and forgeable by a quantum attacker.\",\n};\nconst RULE_C_ECDSA_VERIFY: RuleMeta = {\n id: \"c-ecdsa-verify\",\n title: \"C/OpenSSL ECDSA signature verification\",\n description: \"OpenSSL ECDSA_verify\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Classical ECDSA verification (C/OpenSSL) trusts signatures forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_C_RSA_VERIFY: RuleMeta = {\n id: \"c-rsa-verify\",\n title: \"C/OpenSSL RSA signature verification\",\n description: \"OpenSSL RSA_verify\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Classical RSA signature verification (C/OpenSSL) trusts signatures forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_C_RSA_CRYPT: RuleMeta = {\n id: \"c-rsa-crypt\",\n title: \"C/OpenSSL RSA public-key encryption\",\n description: \"OpenSSL RSA_public_encrypt / RSA_private_decrypt\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Legacy RSA public-key encryption/decryption (C/OpenSSL) is harvest-now-decrypt-later exposed.\",\n};\nconst RULE_C_TLS_VERSION: RuleMeta = {\n id: \"c-tls-legacy-version\",\n title: \"Legacy TLS/SSL version pinned (C/OpenSSL)\",\n description: \"OpenSSL TLSv1_method / SSLv3_method\",\n category: \"tls\",\n severity: \"medium\",\n confidence: \"high\",\n hndl: false,\n cwe: CWE_WEAK_STRENGTH,\n message: \"TLS 1.0 / SSLv3 are deprecated and insecure; require TLS 1.3.\",\n remediation: \"Use TLS_method() with a minimum of TLS 1.3 and prefer PQC-hybrid key exchange.\",\n};\nconst RULE_C_TLS_VERIFY_NONE: RuleMeta = {\n id: \"c-tls-verify-none\",\n title: \"TLS certificate verification disabled (C/OpenSSL)\",\n description: \"OpenSSL SSL_VERIFY_NONE\",\n category: \"tls\",\n severity: \"high\",\n confidence: \"high\",\n hndl: false,\n cwe: CWE_CERT_VALIDATION,\n message: \"SSL_VERIFY_NONE disables TLS certificate verification (MITM risk).\",\n remediation: \"Use SSL_VERIFY_PEER and verify certificates properly.\",\n};\n// --- Mbed TLS (embedded) ---\nconst RULE_C_MBEDTLS_RSA: RuleMeta = {\n id: \"c-mbedtls-rsa-keygen\",\n title: \"Mbed TLS RSA key generation\",\n description: \"Mbed TLS mbedtls_rsa_gen_key\",\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 (Mbed TLS, embedded), which is not quantum-safe.\",\n};\nconst RULE_C_MBEDTLS_EC: RuleMeta = {\n id: \"c-mbedtls-ec-keygen\",\n title: \"Mbed TLS EC key generation\",\n description: \"Mbed TLS mbedtls_ecp_gen_key / mbedtls_ecp_gen_keypair\",\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 (Mbed TLS, embedded). 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_C_MBEDTLS_ECDSA: RuleMeta = {\n id: \"c-mbedtls-ecdsa\",\n title: \"Mbed TLS ECDSA signature\",\n description: \"Mbed TLS mbedtls_ecdsa_sign / write_signature / read_signature / verify\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical ECDSA (Mbed TLS, embedded) is forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_C_MBEDTLS_ECDH: RuleMeta = {\n id: \"c-mbedtls-ecdh\",\n title: \"Mbed TLS ECDH key agreement\",\n description: \"Mbed TLS mbedtls_ecdh_compute_shared / mbedtls_ecdh_calc_secret\",\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 (Mbed TLS, embedded) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_C_MBEDTLS_DH: RuleMeta = {\n id: \"c-mbedtls-dh\",\n title: \"Mbed TLS Diffie-Hellman key exchange\",\n description: \"Mbed TLS mbedtls_dhm_make_public / make_params / calc_secret\",\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 (Mbed TLS, embedded) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\n// --- wolfSSL / wolfCrypt (embedded) ---\nconst RULE_C_WOLF_RSA: RuleMeta = {\n id: \"c-wolfssl-rsa\",\n title: \"wolfSSL RSA key/usage\",\n description: \"wolfCrypt wc_MakeRsaKey / wc_RsaPublicEncrypt / wc_RsaPrivateDecrypt\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Classical RSA key generation / encryption (wolfSSL, embedded) is harvest-now-decrypt-later exposed.\",\n};\nconst RULE_C_WOLF_ECC: RuleMeta = {\n id: \"c-wolfssl-ecc-keygen\",\n title: \"wolfSSL EC key generation\",\n description: \"wolfCrypt wc_ecc_make_key / wc_ecc_make_key_ex\",\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 (wolfSSL, embedded). 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_C_WOLF_ECDSA: RuleMeta = {\n id: \"c-wolfssl-ecdsa\",\n title: \"wolfSSL ECDSA signature\",\n description: \"wolfCrypt wc_ecc_sign_hash / wc_ecc_verify_hash\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical ECDSA (wolfSSL, embedded) is forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_C_WOLF_ECDH: RuleMeta = {\n id: \"c-wolfssl-ecdh\",\n title: \"wolfSSL ECDH key agreement\",\n description: \"wolfCrypt wc_ecc_shared_secret\",\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 (wolfSSL, embedded) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_C_WOLF_DH: RuleMeta = {\n id: \"c-wolfssl-dh\",\n title: \"wolfSSL Diffie-Hellman key exchange\",\n description: \"wolfCrypt wc_DhGenerateKeyPair / wc_DhAgree\",\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 (wolfSSL, embedded) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_C_WOLF_CURVE25519: RuleMeta = {\n id: \"c-wolfssl-curve25519\",\n title: \"wolfSSL X25519 key agreement\",\n description: \"wolfCrypt wc_curve25519_make_key / wc_curve25519_shared_secret\",\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 (wolfSSL, embedded) is modern but classical, and harvest-now-decrypt-later exposed.\",\n};\nconst RULE_C_WOLF_ED25519: RuleMeta = {\n id: \"c-wolfssl-ed25519\",\n title: \"wolfSSL Ed25519 signature\",\n description: \"wolfCrypt wc_ed25519_make_key / wc_ed25519_sign_msg / wc_ed25519_verify_msg\",\n category: \"signature\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"EdDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Ed25519 signatures (wolfSSL, embedded) are classical and forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\n\n/** Detects classical asymmetric crypto in C/C++ (OpenSSL). */\nexport const cDetector: Detector = {\n id: \"c-crypto\",\n description: \"Classical asymmetric crypto in C/C++ (OpenSSL, libsodium, Mbed TLS, wolfSSL)\",\n scope: \"source\",\n language: \"c\",\n rules: [\n RULE_C_RSA,\n RULE_C_EC,\n RULE_C_ECDSA,\n RULE_C_ECDH,\n RULE_C_DSA,\n RULE_C_DH,\n RULE_C_EVP_KEYGEN,\n RULE_C_EVP_DERIVE,\n RULE_C_EVP_CRYPT,\n RULE_C_EVP_SIGN,\n RULE_C_SODIUM_BOX,\n RULE_C_SODIUM_SIGN,\n RULE_C_ECDSA_VERIFY,\n RULE_C_RSA_VERIFY,\n RULE_C_RSA_CRYPT,\n RULE_C_TLS_VERSION,\n RULE_C_TLS_VERIFY_NONE,\n RULE_C_MBEDTLS_RSA,\n RULE_C_MBEDTLS_EC,\n RULE_C_MBEDTLS_ECDSA,\n RULE_C_MBEDTLS_ECDH,\n RULE_C_MBEDTLS_DH,\n RULE_C_WOLF_RSA,\n RULE_C_WOLF_ECC,\n RULE_C_WOLF_ECDSA,\n RULE_C_WOLF_ECDH,\n RULE_C_WOLF_DH,\n RULE_C_WOLF_CURVE25519,\n RULE_C_WOLF_ED25519,\n ],\n appliesTo: (f) => hasExtension(f, C_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_C_RSA, RULE_C_RSA);\n add(RE_C_EC, RULE_C_EC);\n add(RE_C_ECDSA, RULE_C_ECDSA);\n add(RE_C_ECDH, RULE_C_ECDH);\n add(RE_C_DSA, RULE_C_DSA);\n add(RE_C_DH, RULE_C_DH);\n add(RE_C_EVP_KEYGEN, RULE_C_EVP_KEYGEN);\n add(RE_C_EVP_DERIVE, RULE_C_EVP_DERIVE);\n add(RE_C_EVP_CRYPT, RULE_C_EVP_CRYPT);\n add(RE_C_EVP_SIGN, RULE_C_EVP_SIGN);\n add(RE_C_SODIUM_BOX, RULE_C_SODIUM_BOX);\n add(RE_C_SODIUM_SIGN, RULE_C_SODIUM_SIGN);\n add(RE_C_ECDSA_VERIFY, RULE_C_ECDSA_VERIFY);\n add(RE_C_RSA_VERIFY, RULE_C_RSA_VERIFY);\n add(RE_C_RSA_CRYPT, RULE_C_RSA_CRYPT);\n add(RE_C_TLS_VERSION, RULE_C_TLS_VERSION);\n add(RE_C_TLS_VERIFY_NONE, RULE_C_TLS_VERIFY_NONE);\n add(RE_C_MBEDTLS_RSA, RULE_C_MBEDTLS_RSA);\n add(RE_C_MBEDTLS_EC, RULE_C_MBEDTLS_EC);\n add(RE_C_MBEDTLS_ECDSA, RULE_C_MBEDTLS_ECDSA);\n add(RE_C_MBEDTLS_ECDH, RULE_C_MBEDTLS_ECDH);\n add(RE_C_MBEDTLS_DH, RULE_C_MBEDTLS_DH);\n add(RE_C_WOLF_RSA, RULE_C_WOLF_RSA);\n add(RE_C_WOLF_ECC, RULE_C_WOLF_ECC);\n add(RE_C_WOLF_ECDSA, RULE_C_WOLF_ECDSA);\n add(RE_C_WOLF_ECDH, RULE_C_WOLF_ECDH);\n add(RE_C_WOLF_DH, RULE_C_WOLF_DH);\n add(RE_C_WOLF_CURVE25519, RULE_C_WOLF_CURVE25519);\n add(RE_C_WOLF_ED25519, RULE_C_WOLF_ED25519);\n return findings;\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"c.js","sourceRoot":"","sources":["../../src/detectors/c.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Source-code detector for classical asymmetric cryptography in C / C++ using\n * OpenSSL (the dominant crypto library for the ecosystem), libsodium, and — for\n * the embedded / firmware / IoT niche — Mbed TLS (`mbedtls_*`) and wolfSSL /\n * wolfCrypt (`wc_*`). Lexical, same strategy as the other packs; every library's\n * function names are distinctive enough to keep the false-positive risk low.\n *\n * NOTE: scanning OpenSSL's OWN source/headers will naturally light up (the\n * library declares these symbols) — that is inherent to lexical scanning of a\n * crypto library, not a false positive in application code. Matches the classic\n * `*_generate_key` / `ECDSA_sign` / `ECDH_compute_key` call forms plus the\n * `EVP_RSA_gen` helper.\n *\n * HNDL: RSA encryption and (EC)DH key agreement are harvest-now-decrypt-later\n * exposed (hndl:true); ECDSA / DSA signatures are hndl:false but forgeable.\n * `EC_KEY_generate_key` is ambiguous (feeds ECDSA + ECDH), classified\n * conservatively as key-exchange-capable (hndl:true).\n */\nimport type { Detector, Finding, RuleMeta } from \"../types.js\";\nimport { C_EXTENSIONS, eachMatch, findingFromRule, hasExtension } from \"../detect-utils.js\";\nimport { CWE_BROKEN_CRYPTO, CWE_CERT_VALIDATION, CWE_WEAK_STRENGTH } from \"../cwe.js\";\n\nconst RE_C_RSA = /\\bRSA_generate_key(?:_ex)?\\s*\\(|\\bEVP_RSA_gen\\s*\\(/g;\nconst RE_C_EC = /\\bEC_KEY_generate_key\\s*\\(|\\bEC_KEY_new_by_curve_name\\s*\\(/g;\nconst RE_C_ECDSA = /\\bECDSA_do_sign\\s*\\(|\\bECDSA_sign\\s*\\(/g;\nconst RE_C_ECDH = /\\bECDH_compute_key\\s*\\(/g;\nconst RE_C_DSA = /\\bDSA_generate_key\\s*\\(|\\bDSA_generate_parameters(?:_ex)?\\s*\\(/g;\nconst RE_C_DH = /\\bDH_generate_key\\s*\\(|\\bDH_generate_parameters(?:_ex)?\\s*\\(/g;\n// Modern OpenSSL 3.x EVP API (the legacy *_generate_key forms above are\n// deprecated) + libsodium — the biggest C false-negative surface (audit F1).\nconst RE_C_EVP_KEYGEN = /\\bEVP_PKEY_(?:Q_)?keygen\\s*\\(|\\bEVP_PKEY_paramgen\\s*\\(/g;\nconst RE_C_EVP_DERIVE = /\\bEVP_PKEY_derive\\s*\\(/g;\nconst RE_C_EVP_CRYPT = /\\bEVP_PKEY_(?:encrypt|decrypt)\\s*\\(/g;\nconst RE_C_EVP_SIGN = /\\bEVP_DigestSign(?:Init)?\\s*\\(|\\bEVP_DigestVerify(?:Init)?\\s*\\(/g;\n// X25519: crypto_box / crypto_kx key pairs (incl. the fully-qualified\n// curve25519xsalsa20poly1305 form) plus the low-level crypto_scalarmult\n// primitive — all classical Curve25519 key agreement (audit recall gap).\nconst RE_C_SODIUM_BOX =\n /\\bcrypto_box_(?:curve25519xsalsa20poly1305_)?(?:seed_)?keypair\\s*\\(|\\bcrypto_kx_keypair\\s*\\(|\\bcrypto_scalarmult_(?:curve25519|base)\\s*\\(/g;\n// EdDSA: crypto_sign key pairs, including the explicit _ed25519 forms and the\n// deterministic seed_keypair variants (audit recall gap: _ed25519_keypair).\nconst RE_C_SODIUM_SIGN = /\\bcrypto_sign_(?:ed25519_)?(?:seed_)?keypair\\s*\\(/g;\n// Legacy verify / decrypt counterparts to the *_sign / *_encrypt rules above\n// (audit F4-c): the classic OpenSSL RSA/ECDSA verification and RSA raw\n// decryption call forms that the modern EVP + legacy keygen rules don't cover.\nconst RE_C_ECDSA_VERIFY = /\\bECDSA_verify\\s*\\(/g;\nconst RE_C_RSA_VERIFY = /\\bRSA_verify\\s*\\(/g;\nconst RE_C_RSA_CRYPT = /\\bRSA_public_encrypt\\s*\\(|\\bRSA_private_decrypt\\s*\\(/g;\n// C/OpenSSL legacy TLS configuration (mirrors source.ts tlsDetector): forcing a\n// deprecated protocol version or disabling certificate verification.\n// TLSv1_method / TLSv1_1_method (+ the client/server-specific variants) and the\n// SSLv2/SSLv3 method constructors — all pin a deprecated protocol (RFC 8996).\nconst RE_C_TLS_VERSION = /\\b(?:TLSv1(?:_1)?|SSLv2|SSLv3)(?:_client|_server)?_method\\b/g;\nconst RE_C_TLS_VERIFY_NONE = /\\bSSL_VERIFY_NONE\\b/g;\n// Embedded C crypto libraries (the \"embedded\" niche): Mbed TLS and wolfSSL /\n// wolfCrypt. Both use highly-distinctive `mbedtls_*` / `wc_*` prefixes, so the\n// false-positive risk is low. These dominate firmware / IoT / RTOS builds where\n// OpenSSL is too heavy — a codebase surface qScan previously missed entirely.\nconst RE_C_MBEDTLS_RSA = /\\bmbedtls_rsa_gen_key\\s*\\(/g;\nconst RE_C_MBEDTLS_EC = /\\bmbedtls_ecp_gen_key(?:pair)?\\s*\\(/g;\nconst RE_C_MBEDTLS_ECDSA =\n /\\bmbedtls_ecdsa_(?:sign|write_signature|read_signature|verify)\\w*\\s*\\(/g;\nconst RE_C_MBEDTLS_ECDH = /\\bmbedtls_ecdh_(?:compute_shared|calc_secret)\\s*\\(/g;\nconst RE_C_MBEDTLS_DH = /\\bmbedtls_dhm_(?:make_public|make_params|calc_secret)\\s*\\(/g;\nconst RE_C_WOLF_RSA =\n /\\bwc_MakeRsaKey\\s*\\(|\\bwc_RsaPublicEncrypt\\s*\\(|\\bwc_RsaPrivateDecrypt\\s*\\(/g;\nconst RE_C_WOLF_ECC = /\\bwc_ecc_make_key(?:_ex)?\\s*\\(/g;\nconst RE_C_WOLF_ECDSA = /\\bwc_ecc_sign_hash\\s*\\(|\\bwc_ecc_verify_hash\\s*\\(/g;\nconst RE_C_WOLF_ECDH = /\\bwc_ecc_shared_secret\\s*\\(/g;\nconst RE_C_WOLF_DH = /\\bwc_DhGenerateKeyPair\\s*\\(|\\bwc_DhAgree\\s*\\(/g;\nconst RE_C_WOLF_CURVE25519 = /\\bwc_curve25519_(?:make_key|shared_secret)\\s*\\(/g;\nconst RE_C_WOLF_ED25519 = /\\bwc_ed25519_(?:make_key|sign_msg|verify_msg)\\s*\\(/g;\n\nconst RULE_C_RSA: RuleMeta = {\n id: \"c-rsa-keygen\",\n title: \"C/OpenSSL RSA key generation\",\n description: \"OpenSSL RSA_generate_key(_ex) / EVP_RSA_gen\",\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 (C/OpenSSL), which is not quantum-safe.\",\n};\nconst RULE_C_EC: RuleMeta = {\n id: \"c-ec-keygen\",\n title: \"C/OpenSSL EC key generation\",\n description: \"OpenSSL EC_KEY_generate_key / EC_KEY_new_by_curve_name\",\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 (C/OpenSSL). 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_C_ECDSA: RuleMeta = {\n id: \"c-ecdsa\",\n title: \"C/OpenSSL ECDSA signature\",\n description: \"OpenSSL ECDSA_sign / ECDSA_do_sign\",\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 (C/OpenSSL) is forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_C_ECDH: RuleMeta = {\n id: \"c-ecdh\",\n title: \"C/OpenSSL ECDH key agreement\",\n description: \"OpenSSL ECDH_compute_key\",\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 (C/OpenSSL) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_C_DSA: RuleMeta = {\n id: \"c-dsa\",\n title: \"C/OpenSSL DSA key/usage\",\n description: \"OpenSSL DSA_generate_key / DSA_generate_parameters\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"DSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical DSA (C/OpenSSL) is deprecated and forgeable by a quantum attacker.\",\n remediation: \"Rotate off DSA and migrate to ML-DSA-65 (FIPS 204).\",\n};\nconst RULE_C_DH: RuleMeta = {\n id: \"c-dh\",\n title: \"C/OpenSSL Diffie-Hellman key exchange\",\n description: \"OpenSSL DH_generate_key / DH_generate_parameters\",\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 (C/OpenSSL) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_C_EVP_KEYGEN: RuleMeta = {\n id: \"c-evp-keygen\",\n title: \"C/OpenSSL EVP key generation\",\n description: \"OpenSSL 3.x EVP_PKEY_keygen / EVP_PKEY_Q_keygen / paramgen\",\n category: \"key-exchange\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"unknown\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Generates an asymmetric key via the OpenSSL 3.x EVP API (the key type — RSA/EC/DH/X25519 — is set on the CTX). Treated conservatively as key-exchange-capable (harvest-now-decrypt-later).\",\n remediation:\n \"For key agreement: hybrid X25519MLKEM768 (ML-KEM-768). For signatures: ML-DSA-65 (FIPS 204).\",\n};\nconst RULE_C_EVP_DERIVE: RuleMeta = {\n id: \"c-evp-derive\",\n title: \"C/OpenSSL EVP key agreement\",\n description: \"OpenSSL 3.x EVP_PKEY_derive (ECDH / DH shared secret)\",\n category: \"key-exchange\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDH\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Derives an (EC)DH shared secret via the OpenSSL EVP API — broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_C_EVP_CRYPT: RuleMeta = {\n id: \"c-evp-pkey-crypt\",\n title: \"C/OpenSSL EVP public-key encryption\",\n description: \"OpenSSL 3.x EVP_PKEY_encrypt / EVP_PKEY_decrypt (RSA)\",\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/decryption via the OpenSSL EVP API is harvest-now-decrypt-later exposed.\",\n};\nconst RULE_C_EVP_SIGN: RuleMeta = {\n id: \"c-evp-sign\",\n title: \"C/OpenSSL EVP signing\",\n description: \"OpenSSL 3.x EVP_DigestSign* / EVP_DigestVerify*\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"unknown\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Classical signature via the OpenSSL EVP API (RSA/ECDSA/EdDSA) is forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_C_SODIUM_BOX: RuleMeta = {\n id: \"c-libsodium-box\",\n title: \"libsodium X25519 key pair\",\n description:\n \"libsodium crypto_box / crypto_kx keypair + crypto_scalarmult (X25519 key agreement)\",\n category: \"key-exchange\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"X25519\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"libsodium crypto_box uses X25519 key agreement — modern but classical, and harvest-now-decrypt-later exposed.\",\n};\nconst RULE_C_SODIUM_SIGN: RuleMeta = {\n id: \"c-libsodium-sign\",\n title: \"libsodium Ed25519 key pair\",\n description: \"libsodium crypto_sign(_ed25519)(_seed)_keypair (Ed25519 signatures)\",\n category: \"signature\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"EdDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"libsodium crypto_sign uses Ed25519 signatures — classical and forgeable by a quantum attacker.\",\n};\nconst RULE_C_ECDSA_VERIFY: RuleMeta = {\n id: \"c-ecdsa-verify\",\n title: \"C/OpenSSL ECDSA signature verification\",\n description: \"OpenSSL ECDSA_verify\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Classical ECDSA verification (C/OpenSSL) trusts signatures forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_C_RSA_VERIFY: RuleMeta = {\n id: \"c-rsa-verify\",\n title: \"C/OpenSSL RSA signature verification\",\n description: \"OpenSSL RSA_verify\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Classical RSA signature verification (C/OpenSSL) trusts signatures forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_C_RSA_CRYPT: RuleMeta = {\n id: \"c-rsa-crypt\",\n title: \"C/OpenSSL RSA public-key encryption\",\n description: \"OpenSSL RSA_public_encrypt / RSA_private_decrypt\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Legacy RSA public-key encryption/decryption (C/OpenSSL) is harvest-now-decrypt-later exposed.\",\n};\nconst RULE_C_TLS_VERSION: RuleMeta = {\n id: \"c-tls-legacy-version\",\n title: \"Legacy TLS/SSL version pinned (C/OpenSSL)\",\n description: \"OpenSSL TLSv1_method / SSLv3_method\",\n category: \"tls\",\n severity: \"medium\",\n confidence: \"high\",\n hndl: false,\n cwe: CWE_WEAK_STRENGTH,\n message: \"TLS 1.0 / SSLv3 are deprecated and insecure; require TLS 1.3.\",\n remediation: \"Use TLS_method() with a minimum of TLS 1.3 and prefer PQC-hybrid key exchange.\",\n};\nconst RULE_C_TLS_VERIFY_NONE: RuleMeta = {\n id: \"c-tls-verify-none\",\n title: \"TLS certificate verification disabled (C/OpenSSL)\",\n description: \"OpenSSL SSL_VERIFY_NONE\",\n category: \"tls\",\n severity: \"high\",\n confidence: \"high\",\n hndl: false,\n cwe: CWE_CERT_VALIDATION,\n message: \"SSL_VERIFY_NONE disables TLS certificate verification (MITM risk).\",\n remediation: \"Use SSL_VERIFY_PEER and verify certificates properly.\",\n};\n// --- Mbed TLS (embedded) ---\nconst RULE_C_MBEDTLS_RSA: RuleMeta = {\n id: \"c-mbedtls-rsa-keygen\",\n title: \"Mbed TLS RSA key generation\",\n description: \"Mbed TLS mbedtls_rsa_gen_key\",\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 (Mbed TLS, embedded), which is not quantum-safe.\",\n};\nconst RULE_C_MBEDTLS_EC: RuleMeta = {\n id: \"c-mbedtls-ec-keygen\",\n title: \"Mbed TLS EC key generation\",\n description: \"Mbed TLS mbedtls_ecp_gen_key / mbedtls_ecp_gen_keypair\",\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 (Mbed TLS, embedded). 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_C_MBEDTLS_ECDSA: RuleMeta = {\n id: \"c-mbedtls-ecdsa\",\n title: \"Mbed TLS ECDSA signature\",\n description: \"Mbed TLS mbedtls_ecdsa_sign / write_signature / read_signature / verify\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical ECDSA (Mbed TLS, embedded) is forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_C_MBEDTLS_ECDH: RuleMeta = {\n id: \"c-mbedtls-ecdh\",\n title: \"Mbed TLS ECDH key agreement\",\n description: \"Mbed TLS mbedtls_ecdh_compute_shared / mbedtls_ecdh_calc_secret\",\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 (Mbed TLS, embedded) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_C_MBEDTLS_DH: RuleMeta = {\n id: \"c-mbedtls-dh\",\n title: \"Mbed TLS Diffie-Hellman key exchange\",\n description: \"Mbed TLS mbedtls_dhm_make_public / make_params / calc_secret\",\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 (Mbed TLS, embedded) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\n// --- wolfSSL / wolfCrypt (embedded) ---\nconst RULE_C_WOLF_RSA: RuleMeta = {\n id: \"c-wolfssl-rsa\",\n title: \"wolfSSL RSA key/usage\",\n description: \"wolfCrypt wc_MakeRsaKey / wc_RsaPublicEncrypt / wc_RsaPrivateDecrypt\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Classical RSA key generation / encryption (wolfSSL, embedded) is harvest-now-decrypt-later exposed.\",\n};\nconst RULE_C_WOLF_ECC: RuleMeta = {\n id: \"c-wolfssl-ecc-keygen\",\n title: \"wolfSSL EC key generation\",\n description: \"wolfCrypt wc_ecc_make_key / wc_ecc_make_key_ex\",\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 (wolfSSL, embedded). 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_C_WOLF_ECDSA: RuleMeta = {\n id: \"c-wolfssl-ecdsa\",\n title: \"wolfSSL ECDSA signature\",\n description: \"wolfCrypt wc_ecc_sign_hash / wc_ecc_verify_hash\",\n category: \"signature\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message: \"Classical ECDSA (wolfSSL, embedded) is forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\nconst RULE_C_WOLF_ECDH: RuleMeta = {\n id: \"c-wolfssl-ecdh\",\n title: \"wolfSSL ECDH key agreement\",\n description: \"wolfCrypt wc_ecc_shared_secret\",\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 (wolfSSL, embedded) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_C_WOLF_DH: RuleMeta = {\n id: \"c-wolfssl-dh\",\n title: \"wolfSSL Diffie-Hellman key exchange\",\n description: \"wolfCrypt wc_DhGenerateKeyPair / wc_DhAgree\",\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 (wolfSSL, embedded) is broken by Shor's algorithm (harvest-now-decrypt-later).\",\n};\nconst RULE_C_WOLF_CURVE25519: RuleMeta = {\n id: \"c-wolfssl-curve25519\",\n title: \"wolfSSL X25519 key agreement\",\n description: \"wolfCrypt wc_curve25519_make_key / wc_curve25519_shared_secret\",\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 (wolfSSL, embedded) is modern but classical, and harvest-now-decrypt-later exposed.\",\n};\nconst RULE_C_WOLF_ED25519: RuleMeta = {\n id: \"c-wolfssl-ed25519\",\n title: \"wolfSSL Ed25519 signature\",\n description: \"wolfCrypt wc_ed25519_make_key / wc_ed25519_sign_msg / wc_ed25519_verify_msg\",\n category: \"signature\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"EdDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Ed25519 signatures (wolfSSL, embedded) are classical and forgeable by a quantum attacker.\",\n remediation: \"ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205)\",\n};\n\n/** Detects classical asymmetric crypto in C/C++ (OpenSSL). */\nexport const cDetector: Detector = {\n id: \"c-crypto\",\n description: \"Classical asymmetric crypto in C/C++ (OpenSSL, libsodium, Mbed TLS, wolfSSL)\",\n scope: \"source\",\n language: \"c\",\n rules: [\n RULE_C_RSA,\n RULE_C_EC,\n RULE_C_ECDSA,\n RULE_C_ECDH,\n RULE_C_DSA,\n RULE_C_DH,\n RULE_C_EVP_KEYGEN,\n RULE_C_EVP_DERIVE,\n RULE_C_EVP_CRYPT,\n RULE_C_EVP_SIGN,\n RULE_C_SODIUM_BOX,\n RULE_C_SODIUM_SIGN,\n RULE_C_ECDSA_VERIFY,\n RULE_C_RSA_VERIFY,\n RULE_C_RSA_CRYPT,\n RULE_C_TLS_VERSION,\n RULE_C_TLS_VERIFY_NONE,\n RULE_C_MBEDTLS_RSA,\n RULE_C_MBEDTLS_EC,\n RULE_C_MBEDTLS_ECDSA,\n RULE_C_MBEDTLS_ECDH,\n RULE_C_MBEDTLS_DH,\n RULE_C_WOLF_RSA,\n RULE_C_WOLF_ECC,\n RULE_C_WOLF_ECDSA,\n RULE_C_WOLF_ECDH,\n RULE_C_WOLF_DH,\n RULE_C_WOLF_CURVE25519,\n RULE_C_WOLF_ED25519,\n ],\n appliesTo: (f) => hasExtension(f, C_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_C_RSA, RULE_C_RSA);\n add(RE_C_EC, RULE_C_EC);\n add(RE_C_ECDSA, RULE_C_ECDSA);\n add(RE_C_ECDH, RULE_C_ECDH);\n add(RE_C_DSA, RULE_C_DSA);\n add(RE_C_DH, RULE_C_DH);\n add(RE_C_EVP_KEYGEN, RULE_C_EVP_KEYGEN);\n // `EVP_PKEY_derive` is OpenSSL's entry point for BOTH (EC)DH key agreement and the\n // symmetric KDFs (HKDF/scrypt/TLS1-PRF). Real (EC)DH always sets a peer key via\n // `EVP_PKEY_derive_set_peer`; a KDF never does. So only treat it as classical key\n // agreement when a peer is set, or when no KDF context marker is present.\n const hasKdfCtx = /\\bEVP_PKEY_(?:HKDF|SCRYPT|TLS1_PRF)\\b/.test(content);\n if (content.includes(\"EVP_PKEY_derive_set_peer\") || !hasKdfCtx) {\n add(RE_C_EVP_DERIVE, RULE_C_EVP_DERIVE);\n }\n add(RE_C_EVP_CRYPT, RULE_C_EVP_CRYPT);\n // `EVP_DigestSign*` also drives HMAC/CMAC (a symmetric MAC keyed by\n // `EVP_PKEY_new_mac_key(EVP_PKEY_HMAC/CMAC, …)`), which is NOT a classical\n // asymmetric signature. Suppress a `DigestSign*` match ONLY when a MAC key setup\n // sits just before it — per-match, so a real RSA/ECDSA sign elsewhere in the same\n // file is still reported. `DigestVerify*` (no MAC form here) is never suppressed.\n eachMatch(RE_C_EVP_SIGN, content, (m) => {\n const isSign = m[0].includes(\"DigestSign\");\n if (isSign) {\n const back = content.slice(Math.max(0, m.index - 300), m.index);\n if (/EVP_PKEY_new_mac_key|EVP_PKEY_(?:HMAC|CMAC)\\b/.test(back)) return;\n }\n findings.push(\n findingFromRule(RULE_C_EVP_SIGN, {\n file,\n content,\n index: m.index,\n matchLength: m[0].length,\n }),\n );\n });\n add(RE_C_SODIUM_BOX, RULE_C_SODIUM_BOX);\n add(RE_C_SODIUM_SIGN, RULE_C_SODIUM_SIGN);\n add(RE_C_ECDSA_VERIFY, RULE_C_ECDSA_VERIFY);\n add(RE_C_RSA_VERIFY, RULE_C_RSA_VERIFY);\n add(RE_C_RSA_CRYPT, RULE_C_RSA_CRYPT);\n add(RE_C_TLS_VERSION, RULE_C_TLS_VERSION);\n add(RE_C_TLS_VERIFY_NONE, RULE_C_TLS_VERIFY_NONE);\n add(RE_C_MBEDTLS_RSA, RULE_C_MBEDTLS_RSA);\n add(RE_C_MBEDTLS_EC, RULE_C_MBEDTLS_EC);\n add(RE_C_MBEDTLS_ECDSA, RULE_C_MBEDTLS_ECDSA);\n add(RE_C_MBEDTLS_ECDH, RULE_C_MBEDTLS_ECDH);\n add(RE_C_MBEDTLS_DH, RULE_C_MBEDTLS_DH);\n add(RE_C_WOLF_RSA, RULE_C_WOLF_RSA);\n add(RE_C_WOLF_ECC, RULE_C_WOLF_ECC);\n add(RE_C_WOLF_ECDSA, RULE_C_WOLF_ECDSA);\n add(RE_C_WOLF_ECDH, RULE_C_WOLF_ECDH);\n add(RE_C_WOLF_DH, RULE_C_WOLF_DH);\n add(RE_C_WOLF_CURVE25519, RULE_C_WOLF_CURVE25519);\n add(RE_C_WOLF_ED25519, RULE_C_WOLF_ED25519);\n return findings;\n },\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cicd.d.ts","sourceRoot":"","sources":["../../src/detectors/cicd.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"cicd.d.ts","sourceRoot":"","sources":["../../src/detectors/cicd.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;AA4H/D,+EAA+E;AAC/E,eAAO,MAAM,YAAY,EAAE,QAsB1B,CAAC"}
|
package/dist/detectors/cicd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { eachMatch, findingFromRule } from "../detect-utils.js";
|
|
1
|
+
import { eachMatch, findingFromRule, maskCommentLines } from "../detect-utils.js";
|
|
2
2
|
import { CWE_BROKEN_CRYPTO } from "../cwe.js";
|
|
3
3
|
/** True for the CI/CD pipeline definition files this detector inspects. */
|
|
4
4
|
function isCiPipelineFile(filePath) {
|
|
@@ -15,7 +15,9 @@ function isCiPipelineFile(filePath) {
|
|
|
15
15
|
}
|
|
16
16
|
const CI_RULES = [
|
|
17
17
|
{
|
|
18
|
-
|
|
18
|
+
// `sign-blob` precedes `sign` so the longer subcommand wins — otherwise `sign`
|
|
19
|
+
// matches first and the trailing `\b` succeeds at the `-`, never reaching `sign-blob`.
|
|
20
|
+
re: /\bcosign\s+(?:sign-blob|sign|attest|generate-key-pair)\b/g,
|
|
19
21
|
meta: {
|
|
20
22
|
id: "ci-cosign-ecdsa",
|
|
21
23
|
title: "cosign artifact signing (ECDSA)",
|
|
@@ -31,7 +33,11 @@ const CI_RULES = [
|
|
|
31
33
|
},
|
|
32
34
|
},
|
|
33
35
|
{
|
|
34
|
-
|
|
36
|
+
// Bound the span to the gpg invocation ([^\n&|;] stops it crossing `&&`/`|`/`;`
|
|
37
|
+
// into another command's flag), and `(?![\w-])` stops `--sign` matching the
|
|
38
|
+
// `--sign` prefix of an unrelated flag like `--sign-artifacts`. The short forms
|
|
39
|
+
// `-s` (sign) / `-b` (detach-sign) are safe inside the bounded gpg span.
|
|
40
|
+
re: /\bgpg\b[^\n&|;]{0,120}?\s(?:-[sb]\b|--(?:detach-sign|clearsign|sign)(?![\w-]))/g,
|
|
35
41
|
meta: {
|
|
36
42
|
id: "ci-gpg-sign",
|
|
37
43
|
title: "GPG signing (RSA)",
|
|
@@ -63,7 +69,10 @@ const CI_RULES = [
|
|
|
63
69
|
},
|
|
64
70
|
},
|
|
65
71
|
{
|
|
66
|
-
|
|
72
|
+
// Allow intervening flags (the common `codesign --force --options runtime --sign`
|
|
73
|
+
// form), bounded to the codesign invocation so it can't latch onto a later
|
|
74
|
+
// command's `--sign` across `&&`/`|`/`;`.
|
|
75
|
+
re: /\bcodesign\b[^\n&|;]{0,120}?\s(?:-s\b|--sign\b)/g,
|
|
67
76
|
meta: {
|
|
68
77
|
id: "ci-codesign",
|
|
69
78
|
title: "Apple codesign (RSA)",
|
|
@@ -105,8 +114,12 @@ export const cicdDetector = {
|
|
|
105
114
|
appliesTo: isCiPipelineFile,
|
|
106
115
|
detect({ file, content }) {
|
|
107
116
|
const findings = [];
|
|
117
|
+
// A commented-out CI step (`# - run: cosign sign …`, or a `//` line in a
|
|
118
|
+
// Jenkinsfile) is not an active signing step. Mask comment lines first; offsets
|
|
119
|
+
// are preserved so the snippet from the original `content` stays correct.
|
|
120
|
+
const scan = maskCommentLines(content, ["#", "//"]);
|
|
108
121
|
for (const rule of CI_RULES) {
|
|
109
|
-
eachMatch(rule.re,
|
|
122
|
+
eachMatch(rule.re, scan, (m) => {
|
|
110
123
|
findings.push(findingFromRule(rule.meta, { file, content, index: m.index, matchLength: m[0].length }));
|
|
111
124
|
});
|
|
112
125
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cicd.js","sourceRoot":"","sources":["../../src/detectors/cicd.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Config detector: classical signing of build artifacts and code in CI/CD\n * pipelines (GitHub Actions, GitLab CI, Jenkins, Azure Pipelines, CircleCI).\n *\n * Artifact and code signatures are the signature-side analogue of \"harvest now,\n * decrypt later\": a release signed today with a classical key is *forgeable* once\n * a CRQC exists, and long-lived artifacts (container images, released binaries,\n * SBOM attestations) keep verifying against that classical public key for years.\n * So these are flagged `hndl:false` (a signature is not confidentiality — nothing\n * to harvest) but remain real quantum-migration debt.\n *\n * Covered command invocations (distinctive enough inside a CI file that the\n * false-positive risk is low):\n * - `cosign sign|attest|generate-key-pair` → sigstore/cosign uses ECDSA P-256\n * (both key-based and keyless/Fulcio).\n * - `gpg --detach-sign|--clearsign|--sign` → GnuPG, classically RSA.\n * - `jarsigner` → Java JAR signing (RSA/DSA/EC).\n * - `codesign --sign|-s` → Apple code signing (RSA).\n * - `minisign` → Ed25519 signatures.\n *\n * Gated to CI/CD pipeline files so `gpg`/`cosign` mentioned in a shell script or\n * doc does not fire; the surface here is specifically the release pipeline.\n */\nimport type { Detector, Finding, RuleMeta } from \"../types.js\";\nimport { eachMatch, findingFromRule } from \"../detect-utils.js\";\nimport { CWE_BROKEN_CRYPTO } from \"../cwe.js\";\n\n/** True for the CI/CD pipeline definition files this detector inspects. */\nfunction isCiPipelineFile(filePath: string): boolean {\n const lower = filePath.toLowerCase();\n const base = lower.split(\"/\").pop() ?? lower;\n return (\n (lower.includes(\".github/workflows/\") && (lower.endsWith(\".yml\") || lower.endsWith(\".yaml\"))) ||\n base === \".gitlab-ci.yml\" ||\n lower.endsWith(\".gitlab-ci.yml\") ||\n base === \"jenkinsfile\" ||\n lower.endsWith(\".jenkinsfile\") ||\n base === \"azure-pipelines.yml\" ||\n base === \"azure-pipelines.yaml\" ||\n (lower.includes(\".circleci/\") && (lower.endsWith(\".yml\") || lower.endsWith(\".yaml\")))\n );\n}\n\ninterface CiRule {\n re: RegExp;\n meta: RuleMeta;\n}\n\nconst CI_RULES: CiRule[] = [\n {\n re: /\\bcosign\\s+(?:sign|attest|sign-blob|generate-key-pair)\\b/g,\n meta: {\n id: \"ci-cosign-ecdsa\",\n title: \"cosign artifact signing (ECDSA)\",\n description: \"sigstore/cosign signing in a CI pipeline\",\n category: \"signature\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"ECDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"CI pipeline signs artifacts with cosign (ECDSA P-256, key-based or keyless/Fulcio); classical signatures are forgeable once a CRQC exists.\",\n remediation:\n \"Track sigstore's post-quantum signing roadmap (ML-DSA); plan hybrid signing for long-lived release artifacts.\",\n },\n },\n {\n re: /\\bgpg\\b[^\\n]*?\\s--(?:detach-sign|clearsign|sign)\\b/g,\n meta: {\n id: \"ci-gpg-sign\",\n title: \"GPG signing (RSA)\",\n description: \"GnuPG detached/clear signing in a CI pipeline\",\n category: \"signature\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"CI pipeline signs with GPG, classically an RSA signing key; forgeable once a CRQC exists.\",\n remediation: \"Plan migration to ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205) signatures.\",\n },\n },\n {\n re: /\\bjarsigner\\b/g,\n meta: {\n id: \"ci-jarsigner\",\n title: \"Java jarsigner (classical)\",\n description: \"JDK jarsigner code signing in a CI pipeline\",\n category: \"signature\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"CI pipeline signs JARs with jarsigner (classical RSA/DSA/EC signing key); forgeable once a CRQC exists.\",\n remediation:\n \"Plan migration to a PQC signature scheme (ML-DSA-65 / SLH-DSA) as the JDK adds support.\",\n },\n },\n {\n re: /\\bcodesign\\s+(?:-s\\b|--sign\\b)/g,\n meta: {\n id: \"ci-codesign\",\n title: \"Apple codesign (RSA)\",\n description: \"Apple codesign in a CI pipeline\",\n category: \"signature\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"CI pipeline signs with Apple codesign (classical RSA signing identity); forgeable once a CRQC exists.\",\n remediation: \"Classical only today; track Apple's PQC signing support and plan migration.\",\n },\n },\n {\n re: /\\bminisign\\b/g,\n meta: {\n id: \"ci-minisign\",\n title: \"minisign (Ed25519)\",\n description: \"minisign signing in a CI pipeline\",\n category: \"signature\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"EdDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"CI pipeline signs with minisign (Ed25519); modern but classical and forgeable once a CRQC exists.\",\n remediation: \"Plan migration to ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205).\",\n },\n },\n];\n\n/** Detects classical artifact / code signing in CI/CD pipeline definitions. */\nexport const cicdDetector: Detector = {\n id: \"cicd-signing\",\n description: \"Classical artifact / code signing in CI/CD pipelines\",\n scope: \"config\",\n language: \"any\",\n rules: CI_RULES.map((r) => r.meta),\n appliesTo: isCiPipelineFile,\n detect({ file, content }): Finding[] {\n const findings: Finding[] = [];\n for (const rule of CI_RULES) {\n eachMatch(rule.re, content, (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"]}
|
|
1
|
+
{"version":3,"file":"cicd.js","sourceRoot":"","sources":["../../src/detectors/cicd.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Config detector: classical signing of build artifacts and code in CI/CD\n * pipelines (GitHub Actions, GitLab CI, Jenkins, Azure Pipelines, CircleCI).\n *\n * Artifact and code signatures are the signature-side analogue of \"harvest now,\n * decrypt later\": a release signed today with a classical key is *forgeable* once\n * a CRQC exists, and long-lived artifacts (container images, released binaries,\n * SBOM attestations) keep verifying against that classical public key for years.\n * So these are flagged `hndl:false` (a signature is not confidentiality — nothing\n * to harvest) but remain real quantum-migration debt.\n *\n * Covered command invocations (distinctive enough inside a CI file that the\n * false-positive risk is low):\n * - `cosign sign|attest|generate-key-pair` → sigstore/cosign uses ECDSA P-256\n * (both key-based and keyless/Fulcio).\n * - `gpg --detach-sign|--clearsign|--sign` → GnuPG, classically RSA.\n * - `jarsigner` → Java JAR signing (RSA/DSA/EC).\n * - `codesign --sign|-s` → Apple code signing (RSA).\n * - `minisign` → Ed25519 signatures.\n *\n * Gated to CI/CD pipeline files so `gpg`/`cosign` mentioned in a shell script or\n * doc does not fire; the surface here is specifically the release pipeline.\n */\nimport type { Detector, Finding, RuleMeta } from \"../types.js\";\nimport { eachMatch, findingFromRule, maskCommentLines } from \"../detect-utils.js\";\nimport { CWE_BROKEN_CRYPTO } from \"../cwe.js\";\n\n/** True for the CI/CD pipeline definition files this detector inspects. */\nfunction isCiPipelineFile(filePath: string): boolean {\n const lower = filePath.toLowerCase();\n const base = lower.split(\"/\").pop() ?? lower;\n return (\n (lower.includes(\".github/workflows/\") && (lower.endsWith(\".yml\") || lower.endsWith(\".yaml\"))) ||\n base === \".gitlab-ci.yml\" ||\n lower.endsWith(\".gitlab-ci.yml\") ||\n base === \"jenkinsfile\" ||\n lower.endsWith(\".jenkinsfile\") ||\n base === \"azure-pipelines.yml\" ||\n base === \"azure-pipelines.yaml\" ||\n (lower.includes(\".circleci/\") && (lower.endsWith(\".yml\") || lower.endsWith(\".yaml\")))\n );\n}\n\ninterface CiRule {\n re: RegExp;\n meta: RuleMeta;\n}\n\nconst CI_RULES: CiRule[] = [\n {\n // `sign-blob` precedes `sign` so the longer subcommand wins — otherwise `sign`\n // matches first and the trailing `\\b` succeeds at the `-`, never reaching `sign-blob`.\n re: /\\bcosign\\s+(?:sign-blob|sign|attest|generate-key-pair)\\b/g,\n meta: {\n id: \"ci-cosign-ecdsa\",\n title: \"cosign artifact signing (ECDSA)\",\n description: \"sigstore/cosign signing in a CI pipeline\",\n category: \"signature\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"ECDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"CI pipeline signs artifacts with cosign (ECDSA P-256, key-based or keyless/Fulcio); classical signatures are forgeable once a CRQC exists.\",\n remediation:\n \"Track sigstore's post-quantum signing roadmap (ML-DSA); plan hybrid signing for long-lived release artifacts.\",\n },\n },\n {\n // Bound the span to the gpg invocation ([^\\n&|;] stops it crossing `&&`/`|`/`;`\n // into another command's flag), and `(?![\\w-])` stops `--sign` matching the\n // `--sign` prefix of an unrelated flag like `--sign-artifacts`. The short forms\n // `-s` (sign) / `-b` (detach-sign) are safe inside the bounded gpg span.\n re: /\\bgpg\\b[^\\n&|;]{0,120}?\\s(?:-[sb]\\b|--(?:detach-sign|clearsign|sign)(?![\\w-]))/g,\n meta: {\n id: \"ci-gpg-sign\",\n title: \"GPG signing (RSA)\",\n description: \"GnuPG detached/clear signing in a CI pipeline\",\n category: \"signature\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"CI pipeline signs with GPG, classically an RSA signing key; forgeable once a CRQC exists.\",\n remediation: \"Plan migration to ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205) signatures.\",\n },\n },\n {\n re: /\\bjarsigner\\b/g,\n meta: {\n id: \"ci-jarsigner\",\n title: \"Java jarsigner (classical)\",\n description: \"JDK jarsigner code signing in a CI pipeline\",\n category: \"signature\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"CI pipeline signs JARs with jarsigner (classical RSA/DSA/EC signing key); forgeable once a CRQC exists.\",\n remediation:\n \"Plan migration to a PQC signature scheme (ML-DSA-65 / SLH-DSA) as the JDK adds support.\",\n },\n },\n {\n // Allow intervening flags (the common `codesign --force --options runtime --sign`\n // form), bounded to the codesign invocation so it can't latch onto a later\n // command's `--sign` across `&&`/`|`/`;`.\n re: /\\bcodesign\\b[^\\n&|;]{0,120}?\\s(?:-s\\b|--sign\\b)/g,\n meta: {\n id: \"ci-codesign\",\n title: \"Apple codesign (RSA)\",\n description: \"Apple codesign in a CI pipeline\",\n category: \"signature\",\n severity: \"medium\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"CI pipeline signs with Apple codesign (classical RSA signing identity); forgeable once a CRQC exists.\",\n remediation: \"Classical only today; track Apple's PQC signing support and plan migration.\",\n },\n },\n {\n re: /\\bminisign\\b/g,\n meta: {\n id: \"ci-minisign\",\n title: \"minisign (Ed25519)\",\n description: \"minisign signing in a CI pipeline\",\n category: \"signature\",\n severity: \"low\",\n confidence: \"high\",\n algorithm: \"EdDSA\",\n hndl: false,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"CI pipeline signs with minisign (Ed25519); modern but classical and forgeable once a CRQC exists.\",\n remediation: \"Plan migration to ML-DSA-65 (FIPS 204) or SLH-DSA (FIPS 205).\",\n },\n },\n];\n\n/** Detects classical artifact / code signing in CI/CD pipeline definitions. */\nexport const cicdDetector: Detector = {\n id: \"cicd-signing\",\n description: \"Classical artifact / code signing in CI/CD pipelines\",\n scope: \"config\",\n language: \"any\",\n rules: CI_RULES.map((r) => r.meta),\n appliesTo: isCiPipelineFile,\n detect({ file, content }): Finding[] {\n const findings: Finding[] = [];\n // A commented-out CI step (`# - run: cosign sign …`, or a `//` line in a\n // Jenkinsfile) is not an active signing step. Mask comment lines first; offsets\n // are preserved so the snippet from the original `content` stays correct.\n const scan = maskCommentLines(content, [\"#\", \"//\"]);\n for (const rule of CI_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"]}
|
|
@@ -5,11 +5,14 @@
|
|
|
5
5
|
* `GenerateDataKeyPair` select the key type with a `KeySpec` / `KeyPairSpec`
|
|
6
6
|
* (legacy `CustomerMasterKeySpec`) field whose value is `RSA_*` or `ECC_*`.
|
|
7
7
|
*
|
|
8
|
-
* These
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* These field names + `RSA_2048` / `ECC_NIST_P256` values are specific to the AWS
|
|
9
|
+
* KMS/ACM API across every SDK language (JS/TS, Python/boto3, Java, Go, the CLI, JSON
|
|
10
|
+
* policies), so a single lexical rule catches them at very low false-positive rate.
|
|
11
|
+
* Covered forms: the quoted-value SDK/JSON form (`KeySpec: "RSA_2048"`), the camelCase
|
|
12
|
+
* CDK/Pulumi prop form (`customerMasterKeySpec: "RSA_2048"`), and the AWS CDK ENUM
|
|
13
|
+
* form (`kms.KeySpec.RSA_2048`, `KeyAlgorithm.EC_prime256v1`). Terraform uses the
|
|
14
|
+
* snake_case `customer_master_key_spec`, so this never double-counts with the IaC
|
|
15
|
+
* detector.
|
|
13
16
|
*
|
|
14
17
|
* HNDL: an RSA KMS key (encryption/KEM) and an EC KMS key (which AWS KMS can use
|
|
15
18
|
* for ECDH key agreement as well as ECDSA signing) are both harvest-now-decrypt-
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-kms.d.ts","sourceRoot":"","sources":["../../src/detectors/cloud-kms.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cloud-kms.d.ts","sourceRoot":"","sources":["../../src/detectors/cloud-kms.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;AAoE/D,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,EAAE,QAmD9B,CAAC"}
|
|
@@ -1,56 +1,98 @@
|
|
|
1
|
-
import { eachMatch, findingFromRule } from "../detect-utils.js";
|
|
1
|
+
import { DOC_EXTENSIONS, eachMatch, findingFromRule, hasExtension, maskBlockComments, maskCommentLines, } from "../detect-utils.js";
|
|
2
|
+
import { isCloudTemplateFile } from "./cloudformation.js";
|
|
2
3
|
import { CWE_BROKEN_CRYPTO } from "../cwe.js";
|
|
3
|
-
// The AWS KMS key-spec
|
|
4
|
-
//
|
|
5
|
-
// the
|
|
6
|
-
const SPEC_KEYS = "
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
// The AWS KMS / ACM key-spec field names. Both PascalCase (SDK / boto3 / JSON) and
|
|
5
|
+
// camelCase (AWS CDK / Pulumi props) leading letters are accepted. `KeyAlgorithm` is
|
|
6
|
+
// the ACM certificate key spec.
|
|
7
|
+
const SPEC_KEYS = "[Kk]eySpec|[Kk]eyPairSpec|[Cc]ustomerMasterKeySpec|[Kk]eyAlgorithm";
|
|
8
|
+
// (a) The QUOTED-VALUE form: `KeySpec: "RSA_2048"` / `"KeySpec": "RSA_2048"` /
|
|
9
|
+
// `customerMasterKeySpec: "RSA_2048"` (SDK, boto3, JSON, Pulumi props).
|
|
10
|
+
const RE_KMS_RSA = new RegExp(`\\b(?:${SPEC_KEYS})"?\\s*[:=]\\s*['"](?:RSA_\\d+)['"]`, "g");
|
|
11
|
+
const RE_KMS_EC = new RegExp(`\\b(?:${SPEC_KEYS})"?\\s*[:=]\\s*['"](?:ECC_[A-Z0-9_]+|EC_[A-Za-z0-9]+)['"]`, "g");
|
|
12
|
+
// (b) The ENUM-MEMBER form used by AWS CDK: `kms.KeySpec.RSA_2048`,
|
|
13
|
+
// `KeySpec.ECC_NIST_P256`, `KeyAlgorithm.RSA_2048`, `KeyAlgorithm.EC_prime256v1`
|
|
14
|
+
// — an enum reference, no quoted value, so (a) never matches it.
|
|
15
|
+
const RE_KMS_RSA_ENUM = /\b(?:KeySpec|KeyAlgorithm)\.RSA_\d+\b/g;
|
|
16
|
+
const RE_KMS_EC_ENUM = /\b(?:KeySpec|KeyAlgorithm)\.(?:ECC_[A-Z0-9_]+|EC_[A-Za-z0-9]+)\b/g;
|
|
17
|
+
// (c) GCP Cloud KMS: the CryptoKeyVersion algorithm — `RSA_SIGN_PSS_2048_SHA256`,
|
|
18
|
+
// `RSA_DECRYPT_OAEP_*`, `EC_SIGN_P256_SHA256` (enum or quoted string). The
|
|
19
|
+
// `RSA_SIGN`/`RSA_DECRYPT`/`EC_SIGN` prefixes are GCP-KMS-specific.
|
|
20
|
+
const RE_GCP_KMS_RSA = /\bRSA_(?:SIGN|DECRYPT)_[A-Z0-9_]+/g;
|
|
21
|
+
const RE_GCP_KMS_EC = /\bEC_SIGN_[A-Z0-9_]+/g;
|
|
22
|
+
// (d) Azure Key Vault SDK: `createRsaKey` / `createEcKey` (+ `Create*KeyOptions`) and
|
|
23
|
+
// `KeyType.Rsa` / `KeyType.Ec`.
|
|
24
|
+
const RE_AZURE_KV_RSA = /\b[Cc]reateRsaKey(?:Options)?\b|\bKeyType\.Rsa\b/g;
|
|
25
|
+
const RE_AZURE_KV_EC = /\b[Cc]reateEcKey(?:Options)?\b|\bKeyType\.Ec\b/g;
|
|
9
26
|
const RULE_KMS_RSA = {
|
|
10
27
|
id: "cloud-kms-rsa",
|
|
11
|
-
title: "
|
|
12
|
-
description: "AWS KMS
|
|
28
|
+
title: "Cloud KMS RSA key",
|
|
29
|
+
description: "AWS/GCP/Azure KMS RSA key spec (KeySpec / RSA_SIGN_* / createRsaKey)",
|
|
13
30
|
category: "kem",
|
|
14
31
|
severity: "high",
|
|
15
32
|
confidence: "high",
|
|
16
33
|
algorithm: "RSA",
|
|
17
34
|
hndl: true,
|
|
18
35
|
cwe: CWE_BROKEN_CRYPTO,
|
|
19
|
-
message: "Mints a classical RSA key via
|
|
36
|
+
message: "Mints a classical RSA key via a cloud KMS SDK (AWS/GCP/Azure); harvest-now-decrypt-later exposed for encryption.",
|
|
20
37
|
remediation: "Plan migration to PQC as cloud KMS adds ML-KEM / ML-DSA key specs.",
|
|
21
38
|
};
|
|
22
39
|
const RULE_KMS_EC = {
|
|
23
40
|
id: "cloud-kms-ec",
|
|
24
|
-
title: "
|
|
25
|
-
description: "AWS KMS
|
|
41
|
+
title: "Cloud KMS EC key",
|
|
42
|
+
description: "AWS/GCP/Azure KMS EC key spec (ECC_* / EC_SIGN_* / createEcKey)",
|
|
26
43
|
category: "key-exchange",
|
|
27
44
|
severity: "high",
|
|
28
45
|
confidence: "high",
|
|
29
46
|
algorithm: "ECDH",
|
|
30
47
|
hndl: true,
|
|
31
48
|
cwe: CWE_BROKEN_CRYPTO,
|
|
32
|
-
message: "Mints a classical EC key via
|
|
49
|
+
message: "Mints a classical EC key via a cloud KMS SDK (AWS/GCP/Azure); EC keys feed ECDSA signatures and ECDH key agreement (the ECDH path is harvest-now-decrypt-later exposed).",
|
|
33
50
|
remediation: "For key agreement: hybrid X25519MLKEM768 (ML-KEM-768). For signatures: ML-DSA-65 (FIPS 204).",
|
|
34
51
|
};
|
|
35
52
|
/** Detects classical asymmetric keys provisioned via a cloud KMS SDK call. */
|
|
36
53
|
export const cloudKmsDetector = {
|
|
37
54
|
id: "cloud-kms",
|
|
38
|
-
description: "Classical asymmetric keys minted via a cloud KMS SDK
|
|
55
|
+
description: "Classical asymmetric keys minted via a cloud KMS/ACM SDK, AWS CDK, or Pulumi",
|
|
39
56
|
scope: "config",
|
|
40
57
|
language: "any",
|
|
41
58
|
rules: [RULE_KMS_RSA, RULE_KMS_EC],
|
|
42
|
-
|
|
59
|
+
// Skip prose/docs: a README or tutorial showing `KeySpec: "RSA_2048"` to describe
|
|
60
|
+
// the KMS API is not a live key-minting call.
|
|
61
|
+
appliesTo: (f) => !hasExtension(f, DOC_EXTENSIONS),
|
|
43
62
|
detect({ file, content }) {
|
|
44
|
-
// Fast reject: only proceed if
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
!
|
|
63
|
+
// Fast reject: only proceed if an AWS / GCP / Azure KMS key-spec marker is present.
|
|
64
|
+
const lc = content.toLowerCase();
|
|
65
|
+
if (!lc.includes("keyspec") &&
|
|
66
|
+
!lc.includes("keypairspec") &&
|
|
67
|
+
!lc.includes("keyalgorithm") &&
|
|
68
|
+
!lc.includes("rsa_sign") &&
|
|
69
|
+
!lc.includes("rsa_decrypt") &&
|
|
70
|
+
!lc.includes("ec_sign") &&
|
|
71
|
+
!lc.includes("creatersakey") &&
|
|
72
|
+
!lc.includes("createeckey") &&
|
|
73
|
+
!lc.includes("keytype.")) {
|
|
48
74
|
return [];
|
|
49
75
|
}
|
|
76
|
+
// Inside a CloudFormation / ARM template FILE, the cloudformation detector owns
|
|
77
|
+
// the KMS key specs — defer so a KeySpec line is not counted twice. Gated to the
|
|
78
|
+
// template extensions it scans, so an SDK call in a `.ts` stays covered here.
|
|
79
|
+
if (isCloudTemplateFile(file, content))
|
|
80
|
+
return [];
|
|
81
|
+
// Mask comments before scanning so a commented-out `# KeySpec: "RSA_2048"` in a
|
|
82
|
+
// YAML/JSON/HCL config (which the central source-comment stripper doesn't cover)
|
|
83
|
+
// can't fire. Offsets are preserved, so the finding's snippet — built from the
|
|
84
|
+
// original `content` — stays exact.
|
|
85
|
+
const scan = maskCommentLines(maskBlockComments(content), ["#", "//"]);
|
|
50
86
|
const findings = [];
|
|
51
|
-
const add = (re, rule) => eachMatch(re,
|
|
87
|
+
const add = (re, rule) => eachMatch(re, scan, (m) => findings.push(findingFromRule(rule, { file, content, index: m.index, matchLength: m[0].length })));
|
|
52
88
|
add(RE_KMS_RSA, RULE_KMS_RSA);
|
|
53
89
|
add(RE_KMS_EC, RULE_KMS_EC);
|
|
90
|
+
add(RE_KMS_RSA_ENUM, RULE_KMS_RSA);
|
|
91
|
+
add(RE_KMS_EC_ENUM, RULE_KMS_EC);
|
|
92
|
+
add(RE_GCP_KMS_RSA, RULE_KMS_RSA);
|
|
93
|
+
add(RE_GCP_KMS_EC, RULE_KMS_EC);
|
|
94
|
+
add(RE_AZURE_KV_RSA, RULE_KMS_RSA);
|
|
95
|
+
add(RE_AZURE_KV_EC, RULE_KMS_EC);
|
|
54
96
|
return findings;
|
|
55
97
|
},
|
|
56
98
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-kms.js","sourceRoot":"","sources":["../../src/detectors/cloud-kms.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,kFAAkF;AAClF,mFAAmF;AACnF,wDAAwD;AACxD,MAAM,SAAS,GAAG,2CAA2C,CAAC;AAC9D,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,SAAS,SAAS,iCAAiC,EAAE,GAAG,CAAC,CAAC;AACxF,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,SAAS,SAAS,uCAAuC,EAAE,GAAG,CAAC,CAAC;AAE7F,MAAM,YAAY,GAAa;IAC7B,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,iBAAiB;IACxB,WAAW,EAAE,gEAAgE;IAC7E,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,mGAAmG;IACrG,WAAW,EAAE,oEAAoE;CAClF,CAAC;AACF,MAAM,WAAW,GAAa;IAC5B,EAAE,EAAE,cAAc;IAClB,KAAK,EAAE,gBAAgB;IACvB,WAAW,EAAE,gEAAgE;IAC7E,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,0JAA0J;IAC5J,WAAW,EACT,8FAA8F;CACjG,CAAC;AAEF,8EAA8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAa;IACxC,EAAE,EAAE,WAAW;IACf,WAAW,EAAE,gEAAgE;IAC7E,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE,KAAK;IACf,KAAK,EAAE,CAAC,YAAY,EAAE,WAAW,CAAC;IAClC,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI;IACrB,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE;QACtB,qEAAqE;QACrE,IACE,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC5B,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;YAChC,CAAC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAC1C,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,CAAC,EAAU,EAAE,IAAc,EAAQ,EAAE,CAC/C,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;QACJ,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAC9B,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAC5B,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC","sourcesContent":["/**\n * Cloud-KMS SDK detector: classical asymmetric keys minted at RUNTIME through a\n * cloud KMS SDK call — the application-code counterpart to the Terraform detector\n * (which covers the infrastructure-as-code path). AWS KMS `CreateKey` /\n * `GenerateDataKeyPair` select the key type with a `KeySpec` / `KeyPairSpec`\n * (legacy `CustomerMasterKeySpec`) field whose value is `RSA_*` or `ECC_*`.\n *\n * These PascalCase field names + `RSA_2048` / `ECC_NIST_P256` values are specific\n * to the AWS KMS API across every SDK language (JS/TS, Python/boto3, Java, Go,\n * the CLI, JSON policies), so a single lexical rule catches them all with a very\n * low false-positive rate. Terraform uses the snake_case `customer_master_key_spec`\n * instead, so this never double-counts with the IaC detector.\n *\n * HNDL: an RSA KMS key (encryption/KEM) and an EC KMS key (which AWS KMS can use\n * for ECDH key agreement as well as ECDSA signing) are both harvest-now-decrypt-\n * later exposed → hndl:true.\n */\nimport type { Detector, Finding, RuleMeta } from \"../types.js\";\nimport { eachMatch, findingFromRule } from \"../detect-utils.js\";\nimport { CWE_BROKEN_CRYPTO } from \"../cwe.js\";\n\n// The AWS KMS key-spec fields (CreateKey / GenerateDataKeyPair / legacy CMK). The\n// optional `\"?` after the field name accepts both the JS/HCL form (`KeySpec:`) and\n// the JSON form where the key is quoted (`\"KeySpec\":`).\nconst SPEC_KEYS = \"KeySpec|KeyPairSpec|CustomerMasterKeySpec\";\nconst RE_KMS_RSA = new RegExp(`\\\\b(?:${SPEC_KEYS})\"?\\\\s*[:=]\\\\s*['\"]RSA_\\\\d+['\"]`, \"g\");\nconst RE_KMS_EC = new RegExp(`\\\\b(?:${SPEC_KEYS})\"?\\\\s*[:=]\\\\s*['\"]ECC_[A-Z0-9_]+['\"]`, \"g\");\n\nconst RULE_KMS_RSA: RuleMeta = {\n id: \"cloud-kms-rsa\",\n title: \"AWS KMS RSA key\",\n description: \"AWS KMS CreateKey / GenerateDataKeyPair with an RSA_* key spec\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Mints a classical RSA key via the AWS KMS SDK (harvest-now-decrypt-later exposed for encryption).\",\n remediation: \"Plan migration to PQC as cloud KMS adds ML-KEM / ML-DSA key specs.\",\n};\nconst RULE_KMS_EC: RuleMeta = {\n id: \"cloud-kms-ec\",\n title: \"AWS KMS EC key\",\n description: \"AWS KMS CreateKey / GenerateDataKeyPair with an ECC_* key spec\",\n category: \"key-exchange\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDH\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Mints a classical EC key via the AWS KMS SDK; EC keys feed 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};\n\n/** Detects classical asymmetric keys provisioned via a cloud KMS SDK call. */\nexport const cloudKmsDetector: Detector = {\n id: \"cloud-kms\",\n description: \"Classical asymmetric keys minted via a cloud KMS SDK (AWS KMS)\",\n scope: \"config\",\n language: \"any\",\n rules: [RULE_KMS_RSA, RULE_KMS_EC],\n appliesTo: () => true,\n detect({ file, content }): Finding[] {\n // Fast reject: only proceed if a KMS key-spec field name is present.\n if (\n !content.includes(\"KeySpec\") &&\n !content.includes(\"KeyPairSpec\") &&\n !content.includes(\"CustomerMasterKeySpec\")\n ) {\n return [];\n }\n const findings: Finding[] = [];\n const add = (re: RegExp, rule: RuleMeta): void =>\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_KMS_RSA, RULE_KMS_RSA);\n add(RE_KMS_EC, RULE_KMS_EC);\n return findings;\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"cloud-kms.js","sourceRoot":"","sources":["../../src/detectors/cloud-kms.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Cloud-KMS SDK detector: classical asymmetric keys minted at RUNTIME through a\n * cloud KMS SDK call — the application-code counterpart to the Terraform detector\n * (which covers the infrastructure-as-code path). AWS KMS `CreateKey` /\n * `GenerateDataKeyPair` select the key type with a `KeySpec` / `KeyPairSpec`\n * (legacy `CustomerMasterKeySpec`) field whose value is `RSA_*` or `ECC_*`.\n *\n * These field names + `RSA_2048` / `ECC_NIST_P256` values are specific to the AWS\n * KMS/ACM API across every SDK language (JS/TS, Python/boto3, Java, Go, the CLI, JSON\n * policies), so a single lexical rule catches them at very low false-positive rate.\n * Covered forms: the quoted-value SDK/JSON form (`KeySpec: \"RSA_2048\"`), the camelCase\n * CDK/Pulumi prop form (`customerMasterKeySpec: \"RSA_2048\"`), and the AWS CDK ENUM\n * form (`kms.KeySpec.RSA_2048`, `KeyAlgorithm.EC_prime256v1`). Terraform uses the\n * snake_case `customer_master_key_spec`, so this never double-counts with the IaC\n * detector.\n *\n * HNDL: an RSA KMS key (encryption/KEM) and an EC KMS key (which AWS KMS can use\n * for ECDH key agreement as well as ECDSA signing) are both harvest-now-decrypt-\n * later exposed → hndl:true.\n */\nimport type { Detector, Finding, RuleMeta } from \"../types.js\";\nimport {\n DOC_EXTENSIONS,\n eachMatch,\n findingFromRule,\n hasExtension,\n maskBlockComments,\n maskCommentLines,\n} from \"../detect-utils.js\";\nimport { isCloudTemplateFile } from \"./cloudformation.js\";\nimport { CWE_BROKEN_CRYPTO } from \"../cwe.js\";\n\n// The AWS KMS / ACM key-spec field names. Both PascalCase (SDK / boto3 / JSON) and\n// camelCase (AWS CDK / Pulumi props) leading letters are accepted. `KeyAlgorithm` is\n// the ACM certificate key spec.\nconst SPEC_KEYS = \"[Kk]eySpec|[Kk]eyPairSpec|[Cc]ustomerMasterKeySpec|[Kk]eyAlgorithm\";\n// (a) The QUOTED-VALUE form: `KeySpec: \"RSA_2048\"` / `\"KeySpec\": \"RSA_2048\"` /\n// `customerMasterKeySpec: \"RSA_2048\"` (SDK, boto3, JSON, Pulumi props).\nconst RE_KMS_RSA = new RegExp(`\\\\b(?:${SPEC_KEYS})\"?\\\\s*[:=]\\\\s*['\"](?:RSA_\\\\d+)['\"]`, \"g\");\nconst RE_KMS_EC = new RegExp(\n `\\\\b(?:${SPEC_KEYS})\"?\\\\s*[:=]\\\\s*['\"](?:ECC_[A-Z0-9_]+|EC_[A-Za-z0-9]+)['\"]`,\n \"g\",\n);\n// (b) The ENUM-MEMBER form used by AWS CDK: `kms.KeySpec.RSA_2048`,\n// `KeySpec.ECC_NIST_P256`, `KeyAlgorithm.RSA_2048`, `KeyAlgorithm.EC_prime256v1`\n// — an enum reference, no quoted value, so (a) never matches it.\nconst RE_KMS_RSA_ENUM = /\\b(?:KeySpec|KeyAlgorithm)\\.RSA_\\d+\\b/g;\nconst RE_KMS_EC_ENUM = /\\b(?:KeySpec|KeyAlgorithm)\\.(?:ECC_[A-Z0-9_]+|EC_[A-Za-z0-9]+)\\b/g;\n// (c) GCP Cloud KMS: the CryptoKeyVersion algorithm — `RSA_SIGN_PSS_2048_SHA256`,\n// `RSA_DECRYPT_OAEP_*`, `EC_SIGN_P256_SHA256` (enum or quoted string). The\n// `RSA_SIGN`/`RSA_DECRYPT`/`EC_SIGN` prefixes are GCP-KMS-specific.\nconst RE_GCP_KMS_RSA = /\\bRSA_(?:SIGN|DECRYPT)_[A-Z0-9_]+/g;\nconst RE_GCP_KMS_EC = /\\bEC_SIGN_[A-Z0-9_]+/g;\n// (d) Azure Key Vault SDK: `createRsaKey` / `createEcKey` (+ `Create*KeyOptions`) and\n// `KeyType.Rsa` / `KeyType.Ec`.\nconst RE_AZURE_KV_RSA = /\\b[Cc]reateRsaKey(?:Options)?\\b|\\bKeyType\\.Rsa\\b/g;\nconst RE_AZURE_KV_EC = /\\b[Cc]reateEcKey(?:Options)?\\b|\\bKeyType\\.Ec\\b/g;\n\nconst RULE_KMS_RSA: RuleMeta = {\n id: \"cloud-kms-rsa\",\n title: \"Cloud KMS RSA key\",\n description: \"AWS/GCP/Azure KMS RSA key spec (KeySpec / RSA_SIGN_* / createRsaKey)\",\n category: \"kem\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"RSA\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Mints a classical RSA key via a cloud KMS SDK (AWS/GCP/Azure); harvest-now-decrypt-later exposed for encryption.\",\n remediation: \"Plan migration to PQC as cloud KMS adds ML-KEM / ML-DSA key specs.\",\n};\nconst RULE_KMS_EC: RuleMeta = {\n id: \"cloud-kms-ec\",\n title: \"Cloud KMS EC key\",\n description: \"AWS/GCP/Azure KMS EC key spec (ECC_* / EC_SIGN_* / createEcKey)\",\n category: \"key-exchange\",\n severity: \"high\",\n confidence: \"high\",\n algorithm: \"ECDH\",\n hndl: true,\n cwe: CWE_BROKEN_CRYPTO,\n message:\n \"Mints a classical EC key via a cloud KMS SDK (AWS/GCP/Azure); EC keys feed 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};\n\n/** Detects classical asymmetric keys provisioned via a cloud KMS SDK call. */\nexport const cloudKmsDetector: Detector = {\n id: \"cloud-kms\",\n description: \"Classical asymmetric keys minted via a cloud KMS/ACM SDK, AWS CDK, or Pulumi\",\n scope: \"config\",\n language: \"any\",\n rules: [RULE_KMS_RSA, RULE_KMS_EC],\n // Skip prose/docs: a README or tutorial showing `KeySpec: \"RSA_2048\"` to describe\n // the KMS API is not a live key-minting call.\n appliesTo: (f) => !hasExtension(f, DOC_EXTENSIONS),\n detect({ file, content }): Finding[] {\n // Fast reject: only proceed if an AWS / GCP / Azure KMS key-spec marker is present.\n const lc = content.toLowerCase();\n if (\n !lc.includes(\"keyspec\") &&\n !lc.includes(\"keypairspec\") &&\n !lc.includes(\"keyalgorithm\") &&\n !lc.includes(\"rsa_sign\") &&\n !lc.includes(\"rsa_decrypt\") &&\n !lc.includes(\"ec_sign\") &&\n !lc.includes(\"creatersakey\") &&\n !lc.includes(\"createeckey\") &&\n !lc.includes(\"keytype.\")\n ) {\n return [];\n }\n // Inside a CloudFormation / ARM template FILE, the cloudformation detector owns\n // the KMS key specs — defer so a KeySpec line is not counted twice. Gated to the\n // template extensions it scans, so an SDK call in a `.ts` stays covered here.\n if (isCloudTemplateFile(file, content)) return [];\n // Mask comments before scanning so a commented-out `# KeySpec: \"RSA_2048\"` in a\n // YAML/JSON/HCL config (which the central source-comment stripper doesn't cover)\n // can't fire. Offsets are preserved, so the finding's snippet — built from the\n // original `content` — stays exact.\n const scan = maskCommentLines(maskBlockComments(content), [\"#\", \"//\"]);\n const findings: Finding[] = [];\n const add = (re: RegExp, rule: RuleMeta): void =>\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_KMS_RSA, RULE_KMS_RSA);\n add(RE_KMS_EC, RULE_KMS_EC);\n add(RE_KMS_RSA_ENUM, RULE_KMS_RSA);\n add(RE_KMS_EC_ENUM, RULE_KMS_EC);\n add(RE_GCP_KMS_RSA, RULE_KMS_RSA);\n add(RE_GCP_KMS_EC, RULE_KMS_EC);\n add(RE_AZURE_KV_RSA, RULE_KMS_RSA);\n add(RE_AZURE_KV_EC, RULE_KMS_EC);\n return findings;\n },\n};\n"]}
|
|
@@ -22,6 +22,14 @@
|
|
|
22
22
|
* these property names in an unrelated context.
|
|
23
23
|
*/
|
|
24
24
|
import type { Detector } from "../types.js";
|
|
25
|
+
/**
|
|
26
|
+
* True when a file is one THIS detector actually scans (a `.json`/`.yaml`/`.yml`
|
|
27
|
+
* template). The `cloud-kms` and `jwk` detectors defer to this detector ONLY on
|
|
28
|
+
* such files — deferring on any extension that merely contains a marker string
|
|
29
|
+
* (e.g. a `.ts` with an `AWS::KMS` comment) would drop a real finding, since this
|
|
30
|
+
* detector never runs there.
|
|
31
|
+
*/
|
|
32
|
+
export declare function isCloudTemplateFile(file: string, content: string): boolean;
|
|
25
33
|
/**
|
|
26
34
|
* Detects classical asymmetric crypto and legacy TLS config declared in
|
|
27
35
|
* AWS CloudFormation / Azure ARM (incl. Bicep-compiled JSON) templates.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudformation.d.ts","sourceRoot":"","sources":["../../src/detectors/cloudformation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"cloudformation.d.ts","sourceRoot":"","sources":["../../src/detectors/cloudformation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,aAAa,CAAC;AA0B/D;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAE1E;AA6ID;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,QA8CpC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { eachMatch, findingFromRule, hasExtension } from "../detect-utils.js";
|
|
1
|
+
import { eachMatch, findingFromRule, hasExtension, maskCommentLines } from "../detect-utils.js";
|
|
2
2
|
import { CWE_BROKEN_CRYPTO, CWE_WEAK_STRENGTH } from "../cwe.js";
|
|
3
3
|
const CFN_EXTENSIONS = [".json", ".yaml", ".yml"];
|
|
4
4
|
// Fast-reject markers: at least one must appear before any rule regex runs, so
|
|
@@ -10,22 +10,44 @@ const CFN_MARKERS = [
|
|
|
10
10
|
"AWSTemplateFormatVersion",
|
|
11
11
|
"MinimumProtocolVersion",
|
|
12
12
|
"Microsoft.KeyVault",
|
|
13
|
-
|
|
13
|
+
"SslPolicy", // unquoted so a YAML `SslPolicy:` key also gates the file in, not just JSON
|
|
14
14
|
];
|
|
15
|
+
/**
|
|
16
|
+
* True when the content looks like a CloudFormation / ARM deployment template (one
|
|
17
|
+
* of the {@link CFN_MARKERS} is present).
|
|
18
|
+
*/
|
|
19
|
+
function isCloudTemplate(content) {
|
|
20
|
+
return CFN_MARKERS.some((marker) => content.includes(marker));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* True when a file is one THIS detector actually scans (a `.json`/`.yaml`/`.yml`
|
|
24
|
+
* template). The `cloud-kms` and `jwk` detectors defer to this detector ONLY on
|
|
25
|
+
* such files — deferring on any extension that merely contains a marker string
|
|
26
|
+
* (e.g. a `.ts` with an `AWS::KMS` comment) would drop a real finding, since this
|
|
27
|
+
* detector never runs there.
|
|
28
|
+
*/
|
|
29
|
+
export function isCloudTemplateFile(file, content) {
|
|
30
|
+
return hasExtension(file, CFN_EXTENSIONS) && isCloudTemplate(content);
|
|
31
|
+
}
|
|
15
32
|
// Each attribute is matched with an optional quote around the key and `:` as
|
|
16
33
|
// the separator (both plain-JSON and YAML-block-scalar forms use `:`). The
|
|
17
34
|
// `(?<![\w"-])` lookbehind stops a longer/prefixed attribute name from
|
|
18
35
|
// matching on its suffix.
|
|
19
|
-
|
|
20
|
-
|
|
36
|
+
// Match all three AWS KMS spec-key spellings so this detector fully owns KMS keys
|
|
37
|
+
// inside a template (KeySpec, the KeyPair variant, and the legacy CustomerMasterKeySpec).
|
|
38
|
+
const RE_CFN_KMS_RSA = /(?<![\w"-])"?(?:KeySpec|KeyPairSpec|CustomerMasterKeySpec)"?\s*:\s*"?RSA_\d+"?/g;
|
|
39
|
+
const RE_CFN_KMS_EC = /(?<![\w"-])"?(?:KeySpec|KeyPairSpec|CustomerMasterKeySpec)"?\s*:\s*"?ECC_[A-Z0-9_]+"?/g;
|
|
21
40
|
const RE_CFN_ACM_RSA = /(?<![\w"-])"?KeyAlgorithm"?\s*:\s*"?RSA_\d+"?/g;
|
|
22
41
|
const RE_CFN_ACM_EC = /(?<![\w"-])"?KeyAlgorithm"?\s*:\s*"?EC_[A-Za-z0-9]+"?/g;
|
|
23
42
|
// CloudFront: only the pre-2018 "TLSv1" / "TLSv1_2016" / "TLSv1.1_2016"
|
|
24
43
|
// values are legacy; the lookahead delimiter stops this from matching a
|
|
25
44
|
// "TLSv1.2_2018"-style value that merely starts with the same prefix.
|
|
26
|
-
const RE_CFN_CLOUDFRONT_TLS = /(?<![\w"-])"?MinimumProtocolVersion"?\s*:\s*"?(?:TLSv1(?:\.1)?_2016|TLSv1)(?=["'\s,}]|$)/gm;
|
|
27
|
-
// ELB/ALB legacy SSL negotiation policies (named, dated policy strings).
|
|
28
|
-
|
|
45
|
+
const RE_CFN_CLOUDFRONT_TLS = /(?<![\w"-])"?MinimumProtocolVersion"?\s*:\s*"?(?:TLSv1(?:\.1)?_2016|TLSv1|SSLv3)(?=["'\s,}]|$)/gm;
|
|
46
|
+
// ELB/ALB legacy SSL negotiation policies (named, dated policy strings). The value
|
|
47
|
+
// quote is optional (`"?`) so YAML block scalars (`SslPolicy: ELBSecurityPolicy-...`)
|
|
48
|
+
// match too, with a delimiter lookahead so a longer/newer policy name that merely
|
|
49
|
+
// shares the prefix is not matched.
|
|
50
|
+
const RE_CFN_ELB_TLS = /(?<![\w"-])"?SslPolicy"?\s*:\s*"?ELBSecurityPolicy-(?:2016-08|TLS-1-0-\d{4}-\d{2}|TLS-1-1-\d{4}-\d{2})(?=["'\s,}]|$)/g;
|
|
29
51
|
// Azure ARM Microsoft.KeyVault key resource `properties.kty`.
|
|
30
52
|
const RE_CFN_ARM_KV_RSA = /(?<![\w"-])"?kty"?\s*:\s*"?RSA"?(?!\w)/g;
|
|
31
53
|
const RE_CFN_ARM_KV_EC = /(?<![\w"-])"?kty"?\s*:\s*"?EC"?(?!\w)/g;
|
|
@@ -154,16 +176,25 @@ export const cloudformationDetector = {
|
|
|
154
176
|
detect({ file, content }) {
|
|
155
177
|
if (!CFN_MARKERS.some((marker) => content.includes(marker)))
|
|
156
178
|
return [];
|
|
179
|
+
// Mask whole `#` comment lines (YAML CFN/ARM templates ship large commented-out
|
|
180
|
+
// blocks); harmless for JSON, which has no comments. Offsets preserved so finding
|
|
181
|
+
// locations stay exact. `.yaml`/`.json` are not centrally comment-stripped.
|
|
182
|
+
const scan = maskCommentLines(content, ["#"]);
|
|
157
183
|
const findings = [];
|
|
158
|
-
const add = (re, rule) => eachMatch(re,
|
|
184
|
+
const add = (re, rule) => eachMatch(re, scan, (m) => findings.push(findingFromRule(rule, { file, content, index: m.index, matchLength: m[0].length })));
|
|
159
185
|
add(RE_CFN_KMS_RSA, RULE_CFN_KMS_RSA);
|
|
160
186
|
add(RE_CFN_KMS_EC, RULE_CFN_KMS_EC);
|
|
161
187
|
add(RE_CFN_ACM_RSA, RULE_CFN_ACM_RSA);
|
|
162
188
|
add(RE_CFN_ACM_EC, RULE_CFN_ACM_EC);
|
|
163
189
|
add(RE_CFN_CLOUDFRONT_TLS, RULE_CFN_CLOUDFRONT_TLS);
|
|
164
190
|
add(RE_CFN_ELB_TLS, RULE_CFN_ELB_TLS);
|
|
165
|
-
|
|
166
|
-
|
|
191
|
+
// The bare `kty` attribute is generic (every JWK has it), so only treat it as
|
|
192
|
+
// an ARM Key Vault key when the ARM resource type is actually present — otherwise
|
|
193
|
+
// a JWK in a file gated in by another marker (e.g. SslPolicy) would misfire here.
|
|
194
|
+
if (content.includes("Microsoft.KeyVault")) {
|
|
195
|
+
add(RE_CFN_ARM_KV_RSA, RULE_CFN_ARM_KV_RSA);
|
|
196
|
+
add(RE_CFN_ARM_KV_EC, RULE_CFN_ARM_KV_EC);
|
|
197
|
+
}
|
|
167
198
|
return findings;
|
|
168
199
|
},
|
|
169
200
|
};
|