Ginexys
The Authentication Security Checklist: What Gets You Breached, What Protects You, and the Tradeoffs Nobody Talks About
TLDR
Most production auth breaches are not caused by zero-day cryptographic exploits; they are caused by the exact same six failure modes repeated across thousands of web applications. Based on RFC 6749, RFC 7636, OWASP ASVS, and NIST SP 800-63B, this guide details the engineering checklist for securing client-side, edge, and native auth surfaces.| Security Pillar | Primary Risk Factor | Required Engineering Control | Historical High-Profile Failure |
|---|---|---|---|
| Transport | Credentials leaked in URLs/logs | Authorization: Bearer headers + POST body | GitHub (2020) URL token logging |
| Password Hashing | Fast GPU offline brute forcing | Argon2id / bcrypt (cost ≥ 12) / scrypt | LinkedIn (2012) SHA-1 unsalted leak |
| Session Control | Zombie tokens surviving logout | Server Max-Age=0 cookie destruction | Firebase 1-hour post-logout token validity |
| OAuth Protection | Auth code interception / CSRF | PKCE (RFC 7636) + Nonce state validation | Twitter pre-2019 mobile code interception |
| Token Storage | XSS token theft via localStorage | HttpOnly SameSite=Lax cookies & OS Keychain | Auth0 (2020) localStorage advisory |
Standardized implementation flaws cause most web authentication breaches
Every major web application auth breach over the past decade traces back to one of six recurring implementation flaws:
- Credentials in wrong locations: Placing secrets in URL query parameters, server logs, git history, or client
localStorage. - Infinite token lifetimes: Issuing JWTs with
exp: 2099or omitting refresh token rotation. - Unverified signatures: Accepting unverified JWTs or allowing
alg: noneheader bypasses. - OAuth protocol shortcuts: Skipping PKCE on public clients, omitting
statevalidation, or allowing wildcardredirect_urimatches. - Silent session inheritance: Failing to pass
prompt=select_accounton shared terminal screens. - Missing defense in depth: Omitting Content Security Policies (CSP), rate limiting, and generic error messaging.
Edge-enforced boundaries block transport and storage exploits
[Client Browser / SPA / Extension]
/ | \
/ | \
[Bearer Tokens] [HttpOnly Cookies] [OS Keychain]
| | |
v v v
[OAuth PKCE Flow] [Edge Session] [Store Secrets]
\ | /
\ v /
+-----------------------------------+
| Cloudflare Edge / Supabase Identity|
+-----------------------------------+
Credential transport without URL parameters
Never put credentials in URL query strings. URLs are written into browser histories, server access logs, CDN logs, proxy caches, andReferer headers.
// Transport via standard Authorization header
fetch('/api/resource', {
headers: { Authorization: 'Bearer secret_123' }
});
Password hashing with memory-hard algorithms
Avoid fast hash algorithms like MD5, SHA-1, or plain SHA-256. A modern GPU cluster can compute over 10 billion SHA-256 hashes per second. Always enforce memory-hard functions like Argon2id or bcrypt (cost factor ≥ 12). Memory hardness forces the GPU bottleneck onto memory bandwidth rather than compute cores, reducing brute-force attempts by 3 to 4 orders of magnitude.Session management and single-use token rotation
Deleting client-side tokens during logout does not invalidate a JWT on the server. If using short-lived access tokens (15 minutes or less), refresh tokens must implement single-use rotation and reuse detection:// Server-side Refresh Rotation pseudo-logic
async function handleRefresh(oldRefreshToken) {
if (await isTokenReused(oldRefreshToken)) {
// REUSE DETECTED: Immediately revoke all tokens in session family!
await revokeAllFamilySessions(oldRefreshToken);
throw new SecurityError("Refresh token replay attack detected");
}
const newTokenPair = await issueNewTokenPair();
await markTokenUsed(oldRefreshToken);
return newTokenPair;
}
Protecting public clients with PKCE and state validation
Any browser SPA, mobile app, or VS Code webview extension that cannot hide a client secret must use PKCE (RFC 7636). The client generates a randomcode_verifier, derives a code_challenge, and sends the challenge with the initial auth request. The server verifies the code against the verifier during token exchange. Without the verifier, intercepted authorization codes are useless.
Always append prompt=select_account (Google) or prompt=login (GitHub) to prevent silent session inheritance on shared workstations.
Token storage in HttpOnly cookies and OS keychains
localStorage is accessible to any JavaScript running on the page, meaning an XSS vulnerability translates directly into token theft. HttpOnly cookies cannot be read or modified by JavaScript, effectively blocking script-based exfiltration.
For native extensions (such as VS Code plugins), store credentials strictly inside OS Keychain services via vscode.ExtensionContext.secrets.store().
Defense in depth with CSP and per-account rate limits
Deploy strict Content Security Policies on all auth surfaces to prevent script injection:Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com; connect-src 'self' https://auth.ginexys.com; frame-ancestors 'none';
Rate limiting must operate on a per-account basis in addition to per-IP checks, utilizing soft lockouts (delays, CAPTCHAs) rather than hard account lockouts to prevent denial-of-service abuse.
Invariant enforcement secures multi-client architectures
Rule of thumb: Auth security is not about inventing novel cryptography. It is about rigorously enforcing established RFC invariants across every public, private, and secondary code path in your system.
Read this post in the full Engineering Journal →