@profullstack/threatcrush 0.8.0 → 0.9.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/dist/daemon.js CHANGED
@@ -4728,6 +4728,56 @@ var CODE_RULES = [
4728
4728
  severity: "high",
4729
4729
  pattern: /(?:token|secret|password|salt|nonce|session|otp|reset|apikey|api_key)[\w]*\s*[:=][^;\n]{0,60}(?:Math\s*\.\s*random\s*\(|\brandom\s*\.\s*(?:random|randint|choice)\s*\(|\brand\s*\()/i
4730
4730
  },
4731
+ // ── Weak crypto: Python ──────────────────────────────────────────────────
4732
+ //
4733
+ // The generic rules above catch the credential case on the matched line.
4734
+ // These cover what they miss in Python, where the security role of a value is
4735
+ // set by the enclosing function rather than a same-line assignment — a
4736
+ // `random`-drawn token that is *returned*, an MD5 used to *verify* an
4737
+ // artifact — and the broken ciphers, which have no safe use at all.
4738
+ {
4739
+ id: "py-broken-cipher",
4740
+ title: "broken cipher or ECB mode",
4741
+ consequence: "DES, RC2, RC4 and Blowfish are broken or too small to rely on, and ECB encrypts identical plaintext blocks to identical ciphertext, so structure in the data survives encryption. None of them provides the confidentiality their use implies.",
4742
+ cwe: "CWE-327",
4743
+ severity: "high",
4744
+ languages: ["python"],
4745
+ // PyCryptodome/PyCrypto constructors. The mode matters only for AES, whose
4746
+ // safe modes (GCM, CTR, CBC) are common — so AES matches solely on ECB,
4747
+ // while DES/RC4/Blowfish are broken by the algorithm regardless of mode.
4748
+ pattern: /\b(?:DES|DES3|ARC2|RC2|ARC4|RC4|Blowfish|XOR)\s*\.\s*new\s*\(|\bAES\s*\.\s*new\s*\([^)\n]*\bMODE_ECB\b/,
4749
+ inherent: true,
4750
+ guard: false
4751
+ },
4752
+ {
4753
+ id: "py-weak-hash",
4754
+ title: "broken hash algorithm",
4755
+ consequence: "MD5 and SHA-1 have practical collisions, so a digest used for integrity or a signature can be forged to match a value the code trusts.",
4756
+ cwe: "CWE-327",
4757
+ severity: "medium",
4758
+ languages: ["python"],
4759
+ pattern: /\bhashlib\s*\.\s*(?:md5|sha1)\s*\(/,
4760
+ // Python 3.9+ marks a non-security digest — a cache key, an ETag — with
4761
+ // `usedforsecurity=False`, which is exactly the "this MD5 is not a security
4762
+ // claim" signal, so it exempts the line rather than being flagged.
4763
+ lineGuard: /usedforsecurity\s*=\s*False/
4764
+ },
4765
+ {
4766
+ id: "py-predictable-random-seed",
4767
+ title: "PRNG seeded from a predictable value",
4768
+ consequence: "Seeding `random` from the clock or the process id makes its whole sequence reproducible, so anything drawn from it afterwards \u2014 a token, an id, a shuffle \u2014 can be regenerated by guessing the seed.",
4769
+ cwe: "CWE-338",
4770
+ severity: "high",
4771
+ languages: ["python"],
4772
+ // A time- or pid-derived seed, which is the predictable kind. A fixed
4773
+ // integer seed (`random.seed(42)`) is deliberate reproducibility for tests
4774
+ // and simulations, so it is left alone. This needs no credential context:
4775
+ // seeding the global PRNG from the clock is a weakness on its own terms,
4776
+ // which is why the enclosing function's name — that this engine does not
4777
+ // read as evidence anyway — is not consulted.
4778
+ pattern: /\brandom\s*\.\s*seed\s*\([^)\n]*(?:time\s*\.\s*time|datetime|\.\s*now\s*\(|getpid)/,
4779
+ inherent: true
4780
+ },
4731
4781
  {
4732
4782
  id: "redos-nested-quantifier",
4733
4783
  title: "regex with nested unbounded quantifiers",