# jwt pre-scan — JWT misconfiguration signatures

Fixture: `sample-repo/` — three hostile files (hostile.js, views.py,
main.go) plus one clean companion (clean.rb — env-sourced key,
expiry set, verified decode).

- **HIGH** `JWT-UNVERIFIED-READ` — views.py:4 — signature verification explicitly disabled in decode options (`verify_signature: False`)
- **HIGH** `JWT-UNVERIFIED-READ` — main.go:4 — explicitly unverified token parse `ParseUnverified` — signature is never checked
- **HIGH** `JWT-ALG-NONE` — hostile.js:10 — `'none'` in the accepted-algorithms list — unsigned tokens pass
- **HIGH** `JWT-ALG-CONFUSION` — hostile.js:9 — `algorithms: ['RS256','HS256']` mixes asymmetric + symmetric — pubkey-as-HMAC confusion path
- **HIGH** `JWT-INLINE-SECRET` — hostile.js:8 — literal key in `jwt.verify` position (weak/default-looking, 6 chars)
- **HIGH** `JWT-INLINE-SECRET` — hostile.js:15 — literal key in `jwt.sign` position (weak/default-looking, 8 chars)
- **HIGH** `JWT-INLINE-SECRET` — views.py:8 — `JWT_SECRET_KEY` config assigned a literal (weak/default-looking, 8 chars)
- **HIGH** `JWT-KID-UNTRUSTED` — hostile.js:7 — `kid` from the unverified header feeds `fs.readFileSync` — traversal resolves an attacker-chosen key
- **MEDIUM** `JWT-UNVERIFIED-READ` — hostile.js:5 — bare `jwt.decode` with no key/algorithms (jsonwebtoken.decode never verifies); MEDIUM because the file also runs verify calls
- **MEDIUM** `JWT-ALG-UNPINNED` — hostile.js:7,8,11 — verify calls with no `algorithms` allow-list — token header chooses the accepted algorithm
- **MEDIUM** `JWT-NO-EXPIRY` — hostile.js:15, views.py:7 — token minted with no expiry in call/payload window
- **LOW** `JWT-TOKEN-IN-URL` — hostile.js:4, views.py:3 — token read from the query string — URLs are logged and leaked via referer
- **LOW** `JWT-TOKEN-LOCALSTORAGE` — hostile.js:6 — token kept in web storage — readable by any XSS in the origin

`clean.rb` — env-sourced secret, `exp` in payload, verified decode
with algorithm pin: **silent**.

Files scanned: 4 — 8 HIGH / 6 MEDIUM / 3 LOW

Pre-scan only — middleware in other files, key-rotation policy, and
runtime algorithm pinning are invisible to it.
