Description
JavaScript can read sensitive cookies that lack HttpOnly. If XSS occurs, the injected script may obtain their values. HttpOnly does not itself prevent XSS.
Potential impact
- Cookie theft: An XSS payload may read cookie values.
- Session hijacking: Stolen session cookies may allow impersonation.
- Information disclosure: Sensitive cookie data may be exposed.
Remediation
- Set
HttpOnlywhen creating sensitive cookies to prevent JavaScript from reading them. - Address XSS through appropriate input validation and output encoding.
- Configure cookie protections to limit unauthorized access.
Django's CSRF cookie serves a different purpose from its session cookie. CSRF_COOKIE_HTTPONLY=False is not a vulnerability by itself; configure it according to how JavaScript obtains the CSRF token.
Examples
Django cookie settings
Before
python
# Django cookie settings without the flag
SESSION_COOKIE_HTTPONLY = False
After
python
# Django cookie settings with the flag
SESSION_COOKIE_HTTPONLY = True
Flask cookie settings
Before
python
# Flask cookie settings without the flag
from flask import Flask
app = Flask(__name__)
app.config.update(
SESSION_COOKIE_HTTPONLY=False,
)
After
python
# Flask cookie settings with the flag
from flask import Flask
app = Flask(__name__)
app.config.update(
SESSION_COOKIE_HTTPONLY=True,
)
FastAPI cookie settings
Before
python
# FastAPI cookie settings without the flag
from fastapi import FastAPI, Response
import secrets
app = FastAPI()
@app.post("/set-cookie")
async def set_cookie(response: Response):
session_id = secrets.token_urlsafe(32) # An unpredictable session value issued by the server
response.set_cookie(
key="session",
value=session_id,
httponly=False,
secure=True,
samesite="lax",
)
return {"message": "Cookie set"}
After
python
# FastAPI cookie settings with the flag
from fastapi import FastAPI, Response
import secrets
app = FastAPI()
@app.post("/set-cookie")
async def set_cookie(response: Response):
session_id = secrets.token_urlsafe(32) # An unpredictable session value issued by the server
response.set_cookie(
key="session",
value=session_id,
httponly=True,
secure=True,
samesite="lax",
)
return {"message": "Cookie set"}
Explanation
- Before: Without
HttpOnly, JavaScript can read the cookie. - After:
HttpOnlyprevents JavaScript from reading the cookie.