detecting-weak-cryptography

Scan a source tree for weak cryptographic primitives: MD5 / SHA-1 used for security purposes, DES / 3DES / RC4 ciphers, ECB block mode, custom-built crypto (XOR loops, hand-rolled HMAC), hardcoded IVs, predictable random (Math.random / java.util.Random for crypto seeds), missing certificate verification (verify=False, rejectUnauthorized: false). Use when: pre-merge gate on crypto-touching code, audit before SOC2 / PCI assessment, post-incident review when "we found a weakness in our token signing." Threshold: any call to a known-weak algorithm with non-test context, OR cert verification explicitly disabled, OR a custom crypto loop pattern. Trigger with: "scan weak crypto", "find MD5 usage", "check ECB mode", "audit ssl verify", "weak random".

4 Tools
penetration-tester Plugin
security Category

Allowed Tools

ReadBash(python3:*)GlobGrep

Provided by Plugin

penetration-tester

Security testing toolkit with HTTP header analysis, dependency auditing, and static code scanning

security v2.0.0
View Plugin

Installation

This skill is included in the penetration-tester plugin:

/plugin install penetration-tester@claude-code-plugins-plus

Click to copy

Instructions

Detecting Weak Cryptography

Overview

Weak cryptography (CWE-327 Use of a Broken or Risky Cryptographic

Algorithm, CWE-330 Use of Insufficiently Random Values) shows up

when engineers use the convenient API instead of the cryptographic

one. hashlib.md5(password) is faster to type than the correct

bcrypt/argon2 invocation; Math.random() returns a number quickly

without needing to know about crypto.randomBytes().

The fix is universal: use the modern primitive. SHA-256 for general

hashing, bcrypt/argon2/scrypt for passwords, AES-GCM for encryption,

HMAC-SHA256 for signing, secrets / crypto.randomBytes /

SecureRandom for randomness.

When the skill produces findings

Finding Severity Threshold Affected control
MD5 used in security context HIGH hashlib.md5, MessageDigest.MD5, CryptoJS.MD5 CWE-327
SHA-1 used in security context HIGH hashlib.sha1, etc. CWE-327
DES / 3DES cipher CRITICAL DESCrypto, "DES/CBC", "DESede" CWE-327
RC4 cipher CRITICAL "ARC4", "RC4" CWE-327
AES ECB mode CRITICAL "AES/ECB" or MODE_ECB CWE-327
Hardcoded IV (initialization vector) CRITICAL IV literal in source CWE-329
Custom XOR-based "encryption" CRITICAL XOR loop over bytes CWE-327
Predictable random for crypto seed CRITICAL Math.random / java.util.Random / random.random for keys CWE-330
TLS cert verification disabled CRITICAL verify=False, rejectUnauthorized:false, ServerCertificateValidationCallback returning true CWE-295
Hardcoded HMAC secret HIGH Long literal in HMAC constructor CWE-321
Insecure password hashing (no salt, no KDF) CRITICAL hashlib.sha256(password) without bcrypt/argon2 CWE-916

Prerequisites

  • Python 3.9+
  • Source tree on local filesystem

Instructions

Run


python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-weak-cryptography/scripts/scan_weak_crypto.py /path/to/repo

Options: --output, --format, --min-severity, --include-tests,

--languages, --allow-md5-checksums (excludes MD5 used in

non-security contexts like content-addressable storage).

Interpret

CRITICAL = direct cryptographic break available against the

algorithm. CVEs, public attack tools, sometimes pre-computed

tables (rainbow tables for MD5/SHA-1).

HIGH = algorithm collision-broken (MD5, SHA-1) but the specific

use case may tolerate the weakness (file-deduplication checksums,

non-security HMAC). Verify the usage context.

Remediation

See references/PLAYBOOK.md for per-primitive migration. Modern

defaults: SHA-256/SHA-3 for hashing, AES-256-GCM for encryption,

HMAC-SHA-256 for signing, secrets-grade random for keys, bcrypt /

argon2id for password storage.

Examples

Pre-merge gate


python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-weak-cryptography/scripts/scan_weak_crypto.py \
    --min-severity high $(git diff --name-only main...HEAD | tr '\n' ' ')

CI


- name: Weak-crypto scan
  run: |
    python3 plugins/security/penetration-tester/skills/detecting-weak-cryptography/scripts/scan_weak_crypto.py \
        . --min-severity high

Output

JSON / JSONL / Markdown. Exit codes: 0 / 1 / 2.

Error Handling

False positives common on:

  • MD5 used for content-addressable storage (caches, content hashes)

where collision resistance against ATTACKERS isn't needed — use

--allow-md5-checksums.

  • HMAC-MD5 — broken against adversaries but acceptable as an

integrity check inside a TLS session where the channel is

already authenticated.

Verify each finding by reading whether the algorithm's failure

mode (collision, preimage, etc.) is actually exploitable in

context.

Resources

  • references/THEORY.md — Per-primitive attack model (why MD5 /

SHA-1 are collision-broken, why ECB leaks structure, why

Math.random is non-crypto-grade)

  • references/PLAYBOOK.md — Per-language modern-crypto recipes

(Python cryptography library, Node crypto, Java JCA with

modern algorithms, Go crypto/rand + crypto/cipher AEAD)

Ready to use penetration-tester?