Insecure Cookie
debt(d5/e1/b3/t5)
Closest to 'specialist tool catches it' (d5). The detection_hints.tools list includes semgrep, owasp-zap, and lighthouse — all specialist tools rather than default linters or compilers. The issue is not caught by the PHP interpreter or a standard linter; it requires running a SAST scanner (semgrep) or a security proxy (owasp-zap) to detect the missing flags.
Closest to 'one-line patch or single-call swap' (e1). The quick_fix is a single call to session_set_cookie_params() with the correct flags. This is a one-line parameterised fix that resolves the core issue immediately, warranting e1.
Closest to 'localised tax' (b3). The applies_to scope is web context only, and the fix is isolated to cookie/session configuration — typically one or two places in the codebase (session start, setcookie calls). It does not spread across the whole codebase or impose a persistent productivity tax on unrelated work streams.
Closest to 'notable trap' (t5). The misconception field directly states the canonical trap: developers believe HttpOnly alone prevents cookie theft, not realising the Secure flag is also required to prevent interception over plain HTTP. This is a well-documented gotcha that many developers learn only after encountering it, but it does not fully contradict intuition about a similar concept elsewhere — it is more of a partial understanding failure.
Also Known As
TL;DR
Explanation
HttpOnly prevents JavaScript from reading the cookie, blocking XSS-based session theft. Secure restricts the cookie to HTTPS connections, preventing interception on unencrypted networks. SameSite=Strict prevents the browser from sending the cookie on cross-site requests, mitigating CSRF. All three are required for session cookies. Use PHP's array form of setcookie() to set all flags in one call.
Common Misconception
Why It Matters
Common Mistakes
- Not setting HttpOnly on session cookies — XSS can then steal them via document.cookie.
- Not setting the Secure flag — cookies are sent over plain HTTP if available.
- Missing SameSite attribute — defaults vary by browser and may not prevent CSRF.
- Setting overly long expiry on session cookies — a stolen cookie remains valid for months.
Code Examples
// Missing Secure, HttpOnly, SameSite
setcookie('session', $token);
setcookie('session', $token, [
'expires' => time() + 86400,
'path' => '/',
'secure' => true, // HTTPS only
'httponly' => true, // not accessible to JavaScript
'samesite' => 'Strict', // or 'Lax' for cross-site navigation
]);