The crypto hook flags weak cryptographic primitives at the call site: a deprecated cipher, an insecure mode, or a broken digest. It is language-aware, reading each file by its own rules so a Python construct is never flagged on a Rust file, and it is the deterministic engine behind the crypto specialization, which you can run yourself in scan or check mode.
Run it
- Scan the codebase
- Check a snippet
npx lagune read crypto # scans the whole project
npx lagune read crypto --dir src # scans a directory
npx lagune read crypto --file hash.ts # scans a single file
npx lagune read crypto --lang javascript --pattern 'createCipher("aes-256-cbc", k)' # => weak
npx lagune read crypto --lang python --pattern 'hashlib.md5(data)' # => review
npx lagune read crypto --lang go --pattern 'sha256.Sum256(data)' # => safe
The scan prints up to two sections. Weak cryptography found is the finding set (DES/3DES/RC4/Blowfish/RC2, ECB mode): each is a broken cipher primitive, so the hook exits non-zero. Cryptography to review manually is a lead set it cannot judge alone: an MD5/SHA-1 digest (broken for security use, but legitimate as a plain checksum, so intent decides), a non-cryptographic RNG in a security context, or a timing-unsafe comparison. A clean run prints no weak cryptography found.
How to read the verdict
| Verdict | Meaning |
|---|---|
weak | The snippet uses a broken cipher primitive (DES/3DES, RC4, Blowfish, RC2, or ECB mode). |
review | An intent-dependent primitive: an MD5/SHA-1 digest, or a non-cryptographic RNG in a security context. |
safe | The snippet uses crypto, and no weak primitive was found. |
invalid | The snippet contains no recognizable cryptographic construct to judge. |
CLI options
| Option | Value | Description |
|---|---|---|
--pattern | a code snippet | Check one snippet. Repeat to check several, one verdict per line. |
--lang | a language | Required with --pattern: one of javascript, python, go, java, kotlin, php, ruby, rust, csharp, c, cpp. |
--dir | a directory | Scope a scan to a directory. Repeats and combines with --file. |
--file | a file | Scope a scan to a single file. Repeats and combines with --dir. |
With no option it scans the whole project. --pattern needs --lang and cannot be combined with --dir or --file.
Choose what it scans
It leaves out what Git ignores. To leave out more, or to scan what Git ignores, give crypto settings of its own:
npx lagune write add --ignore test/fixtures --checker crypto
{
"checkers": {
"crypto": { "gitignore": false, "ignore": ["test/fixtures"] }
}
}
Configure the hooks covers every setting.
Supported languages
The scan reads these languages, keyed by file extension, each checked against its own cryptographic APIs.
| Language | Weak ciphers (finding) & digests/RNG (review) |
|---|---|
| JavaScript / TypeScript | createCipher, CryptoJS.DES/RC4, quoted *-ecb; MD5/SHA-1 createHash/subtle.digest; Math.random() |
| Python | pycryptodome DES/ARC4/Blowfish.new, algorithms.TripleDES, MODE_ECB; hashlib.md5/sha1; random.* |
| Go | des.NewCipher, rc4.NewCipher, blowfish.NewCipher, NewECBEncrypter; md5/sha1.Sum; math/rand |
| Java / Kotlin | Cipher.getInstance("DES"/…/ECB"); MessageDigest.getInstance("MD5"), HmacMD5; java.util.Random |
| PHP | openssl_encrypt("des-…"/"…-ecb"), mcrypt_*; md5()/sha1(), hash("md5", …); rand()/mt_rand() |
| Ruby | OpenSSL::Cipher.new("des-…"), :ECB; Digest::MD5/SHA1; rand()/Random |
| Rust | Rc4::, Blowfish::, des::, ecb::; Md5::, Sha1::, Hmac<Md5>; SmallRng/XorShiftRng |
| C# | DES/TripleDES/RC2.Create, CipherMode.ECB; MD5/SHA1.Create, HMACMD5; new Random() |
| C / C++ | OpenSSL DES_*/RC4/EVP_des_*, EVP_*_ecb; MD5()/SHA1(), EVP_md5; rand()/random() |
It reads source as text, so a primitive assembled at runtime, hidden behind an alias, or written in a form it does not recognize can slip past. Treat the table as a strong starting point, not a complete inventory.
The hook guarantees the floor (these constructs exist): key management, IV reuse, and RSA padding are judgment the crypto specialization still covers.
Frequently Asked Questions
Run the crypto hook with no flag. Broken ciphers and ECB mode are findings that exit non-zero. An MD5/SHA-1 digest is a review lead, since it is broken for security use but legitimate as a plain checksum.
Only as a review lead in a security context, never as an automatic finding, since randomness is legitimate for jitter or UI ordering.
