Crypto in your code
Post-quantum readiness isn’t only the server. A Worker that does RSA or ECDH itself is exposed too. Flarebox’s code scan finds that, in the project’s Deploy tab under the post-quantum check.
It reads JavaScript and TypeScript, Go, Python and Rust: Python Workers, workers-rs, Go compiled to WebAssembly, and the backend or tooling that often shares the repository. It also reads their dependency manifests. It’s a list to read, each finding with its file and line, not a proof.
What it finds
Section titled “What it finds”| Finding | Risk | Why |
|---|---|---|
Key exchange or encryption: RSA-OAEP, ECDH, X25519 (WebCrypto, node:crypto; Go crypto/rsa, crypto/ecdh; Python cryptography, PyCryptodome, PyNaCl; Rust rsa, x25519-dalek, ring, aws-lc-rs) |
High | Harvest now, decrypt later: recorded data can be decrypted later |
A TLS group list that leaves ML-KEM out: Go CurvePreferences, rustls kx_groups, Python set_ecdh_curve, or the rustls ring provider |
High | It turns off the post-quantum hybrid the library would otherwise use |
| A PEM private key in the source | High | Quantum-vulnerable, and also a leaked secret |
Signatures: RSA, ECDSA, Ed25519 key generation and signing; JWT RS* / PS* / ES* / EdDSA in every language |
Medium | Forgeable once a large quantum computer exists, but only at signing time |
Classical-only libraries, from code or from package.json, go.mod, requirements.txt / pyproject.toml / Pipfile, Cargo.toml |
Low | A dependency to plan around |
| MD5 or SHA-1 in a crypto call | Low | Weak today, quantum or not |
Already post-quantum: ML-KEM / ML-DSA (crypto/mlkem, tls.X25519MLKEM768, aws-lc-rs ML_KEM_*, ml-kem, liboqs, @noble/post-quantum and others) |
Info | Already done |
Each finding has the file, line and column, the line itself, its language, why it matters, and what to use instead in that language.
How it reads code
Section titled “How it reads code”A small lexer per language blanks out comments and keeps string literals apart, so a comment or a log message that mentions RSA doesn’t count:
- JavaScript / TypeScript: regex and template literals.
- Go: raw strings over several lines, runes.
- Python: triple quotes, every string prefix, f-string fields read as code; docstrings count as comments.
- Rust: nested comments, raw strings with any number of
#, character literals told apart from lifetimes;#[cfg(test)]blocks are skipped.
For Go, Python and Rust, each name is resolved through the file’s own imports, so rsa.EncryptOAEP counts only when rsa really is crypto/rsa, and a local variable with the same name doesn’t.
Vendored, build and test paths are skipped for every language: node_modules, vendor, target, .venv, __pycache__, site-packages, test folders, _test.go, test_*.py, .d.ts and minified files. At most 5,000 files of up to 1 MB are read.
Outbound hosts
Section titled “Outbound hosts”The same panel lists the hosts the project talks to, for the post-quantum check: hosts found in the code, and the hosts of https:// URLs in wrangler vars (top level and per environment, with the variable names). It says the list is partial: hosts built at runtime from secrets, KV or the request can’t be found by reading code. Services this Worker calls fills that gap from Cloudflare’s own records. .dev.vars is never read for this.
Accuracy
Section titled “Accuracy”On real code, with every finding checked by hand, 109 of 111 findings were correct across Flarebox’s own Rust, FiloSottile/age and golang-jwt (Go), and pyjwt and python-jose (Python). The two left are names inside the scanner’s own rule tables. Recall wasn’t measured systematically.
On node-forge’s own source (51 files), it found the real RSA code: RSA-OAEP twice (high), RSASSA-PKCS1-v1_5 twice, generateKeyPair('rsa') and generateKeyPairSync('rsa') (medium). On 201 files of @noble and three real Workers projects, it found nothing, with no false positives.