fix(security): explicit JWT algorithm; body size limit#468
Conversation
0fe8e10 to
f100368
Compare
20da232 to
f39aa3e
Compare
Code Review β PR #468: explicit JWT algorithm; body size limitClean, focused PR. Nothing controversial here. β What's good
Pins the signing algorithm so the library can never silently fall back to a different default. Prevents algorithm-confusion attacks if the secret is ever accidentally supplied as an asymmetric key.
Closes the
Makes the body size cap explicit and documented. Protects against body-based DoS and is consistent with the intent of π‘ Minor suggestions1. Test coverage The test plan lists two manual checks:
Both would be straightforward to automate:
Worth adding to the integration/e2e suite so these don't regress silently. 2. The test that previously set a π΄ No blockersBoth changes are minimal, targeted, and correct. Ready to merge once #466 and #467 are in. |
Code Review β PR #468: explicit JWT algorithm; body size limitSummaryClean, targeted hardening. Both changes are low-risk with clear security benefit. β
Explicit
|
Code Review β PR #468: explicit JWT algorithm; body size limitOverallMinimal, focused security hardening. Both changes are correct and add meaningful protection with zero functional regression risk.
|
| Area | Status |
|---|---|
| JWT algorithm pinning (sign) | β Correct |
| JWT algorithm pinning (verify) | β Correct |
| Body size limit | β Correct |
| No remaining unguarded jwt calls | β Verified |
| Test coverage | β No gaps introduced |
Verdict: Approve. Clean, high-signal, low-risk changes.
π€ Reviewed with Claude Code
Code Review β PR #468: explicit JWT algorithm; body size limitSmallest of the three PRs but both changes are well-targeted.
|
Code Review β PR #468Overall: Approve. Both changes are small, correct security improvements with no downsides.
|
Code Review - PR 468: explicit JWT algorithm; body size limitSmall, focused, and correct. Both changes address real attack surface. StrengthsJWT algorithm pinning (src/utils/generateJwt.ts and src/middleware/auth/jsonWebTokens.ts): Explicitly specifying algorithm: 'HS256' on sign and algorithms: ['HS256'] on verify closes the alg:none confusion attack and future-proofs against any library default changes. This is the recommended practice per the jsonwebtoken docs and JWT security best practices. express.json limit: '10kb' (src/index.ts): Making the body size cap explicit documents the intent and protects against JSON bomb / large-payload DoS regardless of future express.json default changes. 10 KB is a reasonable default for a user-management API. NotesThe 10 KB limit applies globally. If any endpoint in this API is expected to accept larger payloads (e.g. file upload metadata, bulk operations), those routes would need a per-route override. Worth a quick scan to confirm no existing route legitimately needs more. There is no corresponding test for the 413 behavior (the test plan mentions a manual check). A supertest case sending a body over 10 KB to any JSON endpoint would lock this in automatically. VerdictBoth changes are correct, minimal, and well-scoped. Approved. |
Code Review: PR 468 - explicit JWT algorithm; body size limitMedium: JWT algorithm pinningSpecifying algorithm: 'HS256' on sign and algorithms: ['HS256'] on verify is best practice - prevents alg: none attacks and protects against future jsonwebtoken library defaults changing. The change is minimal and targeted. The test plan item 'attempt a JWT with alg: none - verify rejected' is worth running manually since this defence-in-depth change is hard to cover with unit tests alone. Medium: Body size limit10kb is a sensible default for a user management API. If future endpoints need larger payloads (e.g. file uploads or bulk operations), those routes can apply their own express.raw() or a route-level express.json override. Worth noting that this limit is now global, so any new endpoint exceeding it will silently return a 413 - something to keep in mind as the project grows. Package version notepackage-lock.json is bumped 0.3.7 to 0.3.8 while package.json targets 0.3.8 to 0.3.9. This is an expected artefact of stacked PRs and should resolve correctly when merged in order (#466 -> #467 -> #468). No action needed, just flagging so it does not surprise the merge reviewer. Clean, focused changes. LGTM pending CI green. |
Code ReviewSummaryTwo small, high-value security hardening changes. Both are correct.
|
f100368 to
7391152
Compare
f39aa3e to
b3ca280
Compare
Code Review:
|
Code Review: PR 468 - explicit JWT algorithm; body size limitOverall: ApproveClean, focused security hardening. Both changes are straightforward and correct. What is goodExplicit HS256 in jwt.verify β adding { algorithms: ['HS256'] } closes the algorithm confusion attack surface. Without this, a crafted token with alg=none or alg=RS256 (using the HMAC secret as an RSA public key) could potentially bypass verification depending on the jsonwebtoken version. Explicit allowlisting is the right pattern. Explicit HS256 in jwt.sign β HS256 was already the implicit default when signing with a string secret, but being explicit future-proofs the code against library behaviour changes and makes the intent clear to readers. 10kb body limit on express.json() β makes the cap intentional and documented rather than relying on library defaults. Reasonable for a user-management API. Minor notes
|
Code ReviewSmall but impactful security hardening. Both changes are correct and the rationale is clear. What is well doneExplicit JWT algorithm - Specifying algorithm: 'HS256' in jwt.sign() and algorithms: ['HS256'] in jwt.verify() closes the alg:none attack and RS256/HS256 confusion attacks. Even if the jsonwebtoken library's default behaviour never changes, explicit beats implicit for security-critical config. Good defensive move. Body size limit - express.json({ limit: '10kb' }) makes the cap intentional and auditable rather than relying on the library's undocumented default. 10kb is sensible for a JSON API. Issues / QuestionsNo test for body size limit The test plan mentions manually verifying a 413 response, but there is no automated test. A simple supertest assertion would lock this in: Not blocking, but the manual step is easy to forget. 10kb limit and future endpoints If any existing or planned endpoint legitimately needs a larger body (bulk user import, base64-encoded content, etc.), it will need its own express.json({ limit: '...' }) middleware applied at the route level. Worth noting in a comment or issue so it is not a surprise later. Minor notes
Verdict: Approve. The changes are correct and well-scoped. Adding an automated test for the 413 response would be a nice follow-up. |
Code Review β PR #468: explicit JWT algorithm; body size limitSmall, focused, correct. Nothing to flag. β Explicit algorithm: 'HS256' on jwt.signgenerateJwtFromUser now passes { algorithm: 'HS256' } to jwt.sign. This documents the intended algorithm and protects against any future change in the library's default behaviour. β Explicit algorithms: ['HS256'] on jwt.verifyauthenticateToken now passes { algorithms: ['HS256'] } to jwt.verify. This is the key defence: without an explicit allowlist, a malicious token crafted with alg: none would bypass signature verification in older or misconfigured versions of the library. Both sides of the JWT lifecycle are now pinned β consistent and correct. β Body size limit 10kbexpress.json({ limit: '10kb' }) makes the cap intentional and visible in code rather than relying on an undocumented library default. 10 KB is appropriate for a user-management API dealing with small JSON payloads. Minor observations
Verdict: Approve β clean, well-targeted, no concerns. |
Code ReviewStrengthsExplicit HS256 algorithm: Correct on both sign and verify. Preventing algorithm confusion (e.g. alg: none or RS256 with an attacker-controlled public key) is a well-known JWT hardening step. The fix is applied consistently: algorithm on jwt.sign in generateJwt.ts and algorithms array on jwt.verify in jsonWebTokens.ts. 10kb body size limit: Sensible default for an auth API. Makes the cap intentional and documented rather than relying on library defaults. IssuesAre there other jwt.verify call sites without algorithms? The deleted xsrfTokens.ts had a bare jwt.verify call (now gone), but it is worth a quick grep across the codebase to confirm no other unguarded verify calls remain, e.g. in passport strategies or token validation utilities. Non-blocking observations
|
Code Review: fix(security): explicit JWT algorithm; body size limitSmall, targeted, and correct. No blockers. StrengthsExplicit JWT algorithm Specifying Body size limit
Issues1. No automated tests for the 413 or algorithm-rejection paths (low) The test plan lists these as manual checks. Both are straightforward to cover with supertest and would give permanent regression protection for these security-critical paths. 2. Other
Notes
|
Restrict JWT sign/verify to HS256 explicitly β prevents algorithm
confusion attacks if the library ever changes its default or an attacker
crafts a token with alg:none.
Add express.json({ limit: '10kb' }) to make the default body size limit
explicit and prevent oversized payload abuse.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
7391152 to
832408d
Compare
b3ca280 to
8536399
Compare
Adds two integration tests to verify the security hardening from this branch: alg:none JWTs are rejected with 401, and bodies >10kb return 413. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Code Review β PR #468: explicit JWT algorithm; body size limitOverall this is a solid, focused security hardening PR. The changes are minimal and correct. β Positives
|
Summary
jwt.signandjwt.verifynow explicitly specifyalgorithm: 'HS256'/algorithms: ['HS256']. Prevents algorithm confusion attacks (e.g.alg: none) if the library ever changes its default or an attacker crafts a malicious token.express.json()now has an explicitlimit: '10kb'β makes the body size cap intentional and documented rather than relying on the library default.Test plan
npm run lint && npm testgreenalg: noneβ verify rejectedπ€ Generated with Claude Code