Affected Versions
| Affected | not applicable (first-party code) |
| Fixed in | not applicable (first-party code) — see fix commit |
| Ecosystem | PHP |
| CVE / GHSA | not assigned |
| CWE | CWE-613 (Insufficient Session Expiration) |
The Vulnerability Explained
PHP's session_start() function creates a session cookie using default configuration values that prioritize compatibility over security. In the vulnerable code, the session was started without explicitly setting the HttpOnly, Secure, or SameSite attributes:
session_start();
echo isset($_SESSION['lasturl']) ? urldecode($_SESSION['lasturl']) : null;
The lasturl session variable stores a redirect target, making this component particularly sensitive to session compromise—an attacker who steals this cookie could manipulate user navigation or impersonate authenticated sessions.
The attack path: When a user accesses the application over unencrypted HTTP (or if an attacker forces HTTP downgrades), the session cookie transmits in plaintext. Network attackers on the same Wi-Fi, ISP infrastructure, or compromised routers can intercept this cookie. Without HttpOnly, XSS payloads could also exfiltrate the cookie via document.cookie. The missing SameSite protection (defaulting to none in older PHP versions) additionally exposed the cookie to cross-site request forgery attacks.
The Fix
The remediation adds session_set_cookie_params() immediately before session_start():
session_set_cookie_params([
'httponly' => true,
'secure' => !empty($_SERVER['HTTPS']),
'samesite' => 'Lax',
]);
session_start();
echo isset($_SESSION['lasturl']) ? urldecode($_SESSION['lasturl']) : null;
Why this specific configuration:
httponly => true: Prevents JavaScript access viadocument.cookie, blocking XSS-based cookie theft even if other vulnerabilities existsecure => !empty($_SERVER['HTTPS']): Dynamically enables Secure flag when HTTPS is active, preventing MITM interception on encrypted connections while maintaining functionality in HTTP development environmentssamesite => 'Lax': Restricts cookie transmission to same-site requests and top-level navigations, stopping CSRF attacks that rely on cross-site POST requests
The !empty($_SERVER['HTTPS']) pattern is particularly important for this codebase—it detects HTTPS presence without requiring hardcoded configuration, making the fix deployable across development, staging, and production without environment-specific changes.
Key Takeaways
- Always configure
session_set_cookie_params()beforesession_start()— PHP's defaults have historically left cookies exposed, and explicit configuration is the only reliable defense - Dynamic Secure flag detection with
$_SERVER['HTTPS']allows single-codebase deployment across HTTP and HTTPS environments while maximizing protection where available - The
lasturlsession storage pattern appears in 61 locations in this codebase; each requires identical cookie hardening to prevent session hijacking across all entry points - Output encoding with
urldecode()does not mitigate cookie theft — transport-layer and cookie-flags security are independent concerns that must both be addressed
How Orbis AppSec Detected This
- Source: The
session_start()function invocation in PHP's session management API - Sink: The session cookie transmitted to the client browser without
Secure,HttpOnly, orSameSiteattributes - Missing control: No prior call to
session_set_cookie_params()orini_set()configuringsession.cookie_httponly,session.cookie_secure, orsession.cookie_samesite - CWE: CWE-613 (Insufficient Session Expiration) — though more precisely CWE-1004 (Sensitive Cookie Without 'HttpOnly' Flag) and CWE-614 (Sensitive Cookie in HTTPS Session Without 'Secure' Flag) describe the cookie-specific aspects
- Fix: Add
session_set_cookie_params()with explicithttponly,secure, andsamesiteconfiguration beforesession_start()
Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.
Conclusion
This vulnerability exemplifies how PHP's convenient session_start() API conceals dangerous defaults. The lasturl redirect tracking functionality—seemingly simple session storage—became a session hijacking vector because the cookie carrying that session data traveled unprotected. The fix demonstrates that secure session management in PHP requires explicit configuration: session_set_cookie_params() must precede every session_start(), with careful attention to environment-aware Secure flag deployment.