Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
The English summary is being prepared. Showing the original description.
Use when the diff touches login, password storage, sessions, cookies, JWT verification, OAuth/OIDC or SAML flows, MFA and step-up, passkeys/WebAuthn, account linking and recovery, password reset, webhook signatures, API keys, mTLS identity or headers used to identify a caller
The English summary is being prepared. Showing the original description.
See how to installReview the instructions the agent will receive before you install.
Authentication bugs are rarely missing code; they are code that verifies the wrong thing, verifies with the wrong key, or trusts a value the attacker sends. Read every check as "what exactly is compared to what, and who chose each side?"
Core principle: the server decides the algorithm, the key, the audience and the identity — never the token, the header or the client.
# ❌
user.password = hashlib.sha256(pw.encode()).hexdigest()
# ✅
user.password = argon2.PasswordHasher().hash(pw) # or Django's make_password
// ❌ decode() does not verify; the header's alg is trusted
const claims = jwt.decode(token);
// ❌ no algorithm pinned: an RS256 public key can be used as an HS256 secret
const claims = jwt.verify(token, publicKey);
// ✅
const claims = jwt.verify(token, publicKey, { algorithms: ["RS256"], audience: "api", issuer: ISS });
# ❌
jwt.decode(token, options={"verify_signature": False})
# ✅
jwt.decode(token, key, algorithms=["RS256"], audience="api", issuer=ISS)
Also: alg: none accepted; exp/aud/iss not checked; the key chosen by a kid header used in a file path or SQL query; keys fetched from a token-supplied jku/x5u URL (SSRF and forged keys); a token accepted for a different audience than this service.
Domain=.example.com is sent to every subdomain — including one that serves user content or a third-party app; a sibling cookie with the same name and a broader path can shadow it.HttpOnly, Secure, SameSite missing is hardening — report only with a concrete chain (a session cookie readable by script on a page with a real XSS sink in this diff).localStorage: not a finding by itself; it raises the impact of an XSS.state missing or not compared on callback → login CSRF / account linking to the attacker's identity (CWE-352).redirect_uri validated by prefix or substring on the authorization server side → code/token theft.nonce not checked in flows that return an ID token from the front channel.aud check).email_verified: false → account takeover.// ❌ any client sets this header
const userId = req.header("X-User-Id");
// ❌ Express trusts every hop's X-Forwarded-For for IP allowlists
app.set("trust proxy", true);
Headers like X-User-Id, X-Remote-User, X-Forwarded-For, X-Real-IP identify a caller only when an authenticating proxy sets them and strips client copies — confirm that in the repo's deployment config, not by assumption. X-Forwarded-Host/Host used to build a password-reset or magic-link URL sends the token to the attacker's domain:
# ❌ host header injection: the reset link points wherever the request's Host said
link = f"https://{request.headers['Host']}/reset?token={token}"
# ✅
link = f"{settings.PUBLIC_BASE_URL}/reset?token={token}"
== instead of hmac.Equal/subtle.ConstantTimeCompare, hmac.compare_digest, crypto.timingSafeEqual, MessageDigest.isEqual: a non-blocking note at most — remote timing is rarely practical.Use the library's verify call and read what it is given: the challenge must be the one issued to this session and consumed once; the RP ID and expected origin must be fixed server-side values; at authentication, the credential must belong to the account being signed in, and the userHandle → account mapping must come from the server's own record. Require user verification when the policy says so. A signature counter matters only where the product treats a regression as a clone signal.
Audience, Recipient, NotOnOrAfter and InResponseTo not checked; assertions not recorded to stop replay.Draw the account before and after: each new edge — an IdP, a passkey, an email, a phone, a device — needs a current authenticated session, proof of ownership of the new identity, the step-up the policy requires, and callback state bound to the account that started it.
?org=, X-Org-Id) overrides the key's own binding.X-Client-Cert, X-SSL-Client-S-DN) trusted from any peer rather than only from the terminating proxy (http-cache-and-proxy-trust §5); a certificate subject's free text mapped to an account; a certificate that fails validation falling back to bearer-only or anonymous access.Authentication bypass, forged tokens or SAML assertions accepted, or account takeover → CRITICAL. Reset-link host injection, unsigned state-changing webhooks, OAuth state/redirect_uri flaws, MFA enrollment without the existing factor, account linking without ownership proof, an API key reaching another tenant → HIGH. Fixation, logout that does not revoke → MEDIUM.
jwt.decode unsafe in code that only reads claims of a token the server already verified upstream — check the middleware.SameSite attribute with no state-changing endpoint relying on that cookie.verify=False, verify_signature: False, ignoreExpiration: true, algorithms omitted.trust proxy set to true, or X-Forwarded-* read for an authorization decision.NameID.OWASP Top 10:2025 A07 Authentication Failures · ASVS 5.0 V6 Authentication, V7 Session Management, V9 Self-contained Tokens, V10 OAuth and OIDC · CWE-208, 290, 304, 347, 348, 384, 613, 640, 916 · W3C WebAuthn Level 3 · OWASP SAML Security Cheat Sheet · RFC 9700 OAuth 2.0 Security Best Current Practice
No reviews yet. Tell others what you thought.
No login needed. Share how it worked for you, ask a question, or note where it did not run.
No comments yet. Be the first to write one.
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
The English summary is being prepared. Showing the original description.
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
The English summary is being prepared. Showing the original description.
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
The English summary is being prepared. Showing the original description.
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
The English summary is being prepared. Showing the original description.
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
The English summary is being prepared. Showing the original description.
Use when the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here
The English summary is being prepared. Showing the original description.