# Crypto mis-use pre-scan (ARION service)

Deterministic source-code scanner for weak cryptography and insecure
randomness. No network, no execution, no secrets required — works fully
offline on a checked-out tree.

**Honest scope:** this is a *pre-scan*, not an audit. Files are read
line-wise — it does not follow dataflow, judge protocol soundness, or
see runtime config. A FLAG means "this line deserves human review"; a
clean report is not proof the code is cryptographically sound.

## Coverage

- **Broken hashes** — `WEAK-HASH` for MD5/SHA-1 call sites (Python,
  Node, Java, Ruby, PHP, Go, OpenSSL). Severity is context-tiered:
  HIGH next to password/token/signature/integrity wording, LOW next
  to benign wording (etag/cache/dedup/content-addressing), MEDIUM
  otherwise.
- **Broken ciphers/modes** — `WEAK-CIPHER` (DES, 3DES/DESede, RC2,
  RC4, Blowfish, RSA1_5), `ECB-MODE`, `NODE-LEGACY-CIPHER`
  (createCipher/createDecipher — MD5 key derivation, no salt).
- **Non-CSPRNG for secrets** — `WEAK-RNG` (random.*, Math.random,
  mt_rand/rand/uniqid, java.util.Random, math/rand, srand). HIGH when
  security context is found on the line or in the enclosing function
  signature (two-line lookback); LOW otherwise. `PREDICTABLE-SEED`
  for constant/time seeds.
- **Hard-coded material** — `HARDCODED-KEY` for literal key-like
  assignments (env/config reads suppressed), `STATIC-IV` for
  string/zero IVs and fixed nonces.
- **TLS verification off** — `TLS-VERIFY-OFF`: verify=False,
  CERT_NONE, rejectUnauthorized:false, NODE_TLS_REJECT_UNAUTHORIZED=0,
  InsecureSkipVerify:true, CURLOPT_SSL_VERIFYPEER 0, VERIFY_NONE,
  --insecure, trust-all managers.
- **JWT misuse** — `JWT-NONE` (alg none), `JWT-NOVERIFY` (decode with
  signature verification disabled), `JWT-WEAK-SECRET` (short literal
  signing secret).
- **Password fast-hash** — `PASSWORD-FASTHASH` for md5/sha*/createHash
  applied to a password (bcrypt/argon2/scrypt/PBKDF2 call sites are
  not flagged).
- **Key size** — `SMALL-RSA-KEY` for RSA generation < 2048 bits.
- **Home-rolled crypto** — `XOR-ENCRYPT` (LOW) for encrypt/decrypt
  helpers whose bodies XOR data.

## Usage

```
python3 crypto_prescan.py <file-or-repo-dir> [--json]
python3 crypto_prescan.py --selftest     # 21 vectors
```

Stdlib only (Python 3.8+). Exit 0 = no HIGH/MEDIUM findings,
1 = findings, 2 = usage error. Accepts a single file or walks a repo
(skipping `.git`, `node_modules`, `vendor`, `dist`, `build`).

Output is a markdown report (see `sample-report.md`) or JSON with
`--json` for piping into other tooling.

## Validation

- 21 selftest vectors pass — every rule class plus clean controls
  (secrets.*, bcrypt, env-read keys) that must NOT flag.
- Live-validated on a real service repo: flagged a deliberate
  `rejectUnauthorized: false` postgres-pool setting for review
  (true positive — the code comment documents the trade-off), and
  tiered test-file Math.random uses to LOW.
