CWE-614: Sensitive Cookie Without 'Secure' Flag - Python
Overview
Sensitive Cookie Without 'Secure' Flag in Python web applications occurs when cookies containing sensitive data (session IDs, authentication tokens, user identifiers) are set without the Secure flag. This allows cookies to be transmitted over unencrypted HTTP connections, exposing them to interception attacks such as man-in-the-middle (MITM) attacks, network sniffing, and session hijacking.
Common Python Vulnerability Scenarios:
- Setting session cookies without
secure=Truein Flask - Django session cookies without
SESSION_COOKIE_SECURE = True - FastAPI cookies missing
secureparameter - Custom authentication cookies without proper flags
- Remember-me cookies transmitted over HTTP
- OAuth state cookies without secure flag
Python Framework Cookie Security:
- Flask:
response.set_cookie(secure=True, httponly=True, samesite='Strict') - Django:
SESSION_COOKIE_SECURE = Truein settings - FastAPI:
response.set_cookie(secure=True, httponly=True, samesite='strict') - Bottle:
response.set_cookie(secure=True, httponly=True)
Primary Defence: Set secure=True, httponly=True, and samesite='Strict' on all cookies containing sensitive data, and enable SESSION_COOKIE_SECURE in production.
Common Vulnerable Patterns
Flask Cookie Without Secure Flag
# VULNERABLE - Session cookie without Secure flag
from flask import Flask, request, make_response
import secrets
app = Flask(__name__)
@app.route('/login', methods=['POST'])
def login():
username = request.form.get('username')
password = request.form.get('password')
if authenticate_user(username, password):
session_token = secrets.token_hex(32)
response = make_response({'status': 'logged_in'})
# VULNERABLE - Missing secure=True
response.set_cookie(
'session_id',
session_token,
httponly=True,
max_age=3600
)
return response
return {'error': 'Invalid credentials'}, 401
def authenticate_user(username, password):
# Authentication logic
return True
Why this is vulnerable:
- Cookie transmitted over HTTP
- Susceptible to MITM attacks
- Network sniffing can capture session token
- No protection over insecure connections
Django Without SESSION_COOKIE_SECURE
# VULNERABLE - SESSION_COOKIE_SECURE not set to True
DEBUG = False
ALLOWED_HOSTS = ['example.com']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
]
# VULNERABLE - These should be True in production
SESSION_COOKIE_SECURE = False # BAD!
CSRF_COOKIE_SECURE = False # BAD!
SESSION_COOKIE_HTTPONLY = True # Good, but not enough
from django.contrib.auth import login
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
@require_http_methods(["POST"])
def user_login(request):
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
# VULNERABLE - Session cookie sent without Secure flag
login(request, user)
return JsonResponse({'status': 'logged_in'})
return JsonResponse({'error': 'Invalid credentials'}, status=401)
Why this is vulnerable:
SESSION_COOKIE_SECURE = Falseallows HTTP transmission- CSRF token also vulnerable
- Django sessions exposed to interception
- Production misconfiguration
FastAPI Cookie Without Secure Flag
# VULNERABLE - FastAPI custom authentication without secure cookies
from fastapi import FastAPI, Response, Request, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel
import secrets
from datetime import datetime, timedelta
app = FastAPI()
# In-memory session store (demo purposes)
sessions = {}
class LoginRequest(BaseModel):
username: str
password: str
@app.post("/login")
async def login(request: LoginRequest, response: Response):
if authenticate_user(request.username, request.password):
session_token = secrets.token_urlsafe(32)
# Store session
sessions[session_token] = {
'username': request.username,
'created_at': datetime.now()
}
# VULNERABLE - Missing secure=True
response.set_cookie(
key="session_token",
value=session_token,
httponly=True,
max_age=1800,
samesite="lax"
)
return {"status": "logged_in"}
raise HTTPException(status_code=401, detail="Invalid credentials")
def authenticate_user(username: str, password: str) -> bool:
# Authentication logic
return True
Why this is vulnerable:
secureparameter not set- Cookie sent over HTTP
- Session token exposed to network attacks
- Missing critical security flag
Remember-Me Cookie Without Secure Flag
# VULNERABLE - Remember-me functionality with insecure cookies
from flask import Flask, request, make_response
import secrets
import hashlib
from datetime import datetime, timedelta
app = Flask(__name__)
@app.route('/login', methods=['POST'])
def login_with_remember():
username = request.form.get('username')
password = request.form.get('password')
remember_me = request.form.get('remember_me') == 'true'
if authenticate_user(username, password):
session_token = secrets.token_hex(32)
response = make_response({'status': 'logged_in'})
# Session cookie (also vulnerable, but short-lived)
response.set_cookie(
'session_id',
session_token,
httponly=True,
max_age=3600
)
if remember_me:
# VULNERABLE - Long-lived remember-me cookie without Secure flag
remember_token = secrets.token_hex(64)
# Store token in database
store_remember_token(username, remember_token)
response.set_cookie(
'remember_me',
remember_token,
httponly=True,
max_age=30*24*3600 # 30 days - VERY vulnerable!
)
return response
return {'error': 'Invalid credentials'}, 401
def store_remember_token(username, token):
# Database storage
pass
def authenticate_user(username, password):
return True
Why this is vulnerable:
- Long-lived cookies especially dangerous
- 30-day exposure window
- No secure flag = persistent vulnerability
- Enables long-term session hijacking
Custom Auth Cookie Without Proper Flags
# VULNERABLE - Custom JWT cookie without proper security
from flask import Flask, request, make_response
import jwt
from datetime import datetime, timedelta
app = Flask(__name__)
SECRET_KEY = 'your-secret-key'
@app.route('/api/login', methods=['POST'])
def api_login():
username = request.json.get('username')
password = request.json.get('password')
if authenticate_user(username, password):
# Create JWT token
payload = {
'username': username,
'exp': datetime.utcnow() + timedelta(hours=1)
}
token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
response = make_response({'status': 'success'})
# VULNERABLE - Multiple issues
response.set_cookie(
'auth_token',
token,
max_age=3600
# Missing: secure=True
# Missing: httponly=True
# Missing: samesite attribute
)
return response
return {'error': 'Authentication failed'}, 401
def authenticate_user(username, password):
return True
Why this is vulnerable:
- No
secure=Trueflag - No
httponly=True(XSS vulnerable) - No
samesiteattribute (CSRF vulnerable) - Triple vulnerability in one cookie
OAuth State Cookie Without Secure Flag
# VULNERABLE - OAuth state cookie without security flags
from flask import Flask, request, redirect, make_response
import secrets
app = Flask(__name__)
@app.route('/oauth/authorize')
def oauth_authorize():
# Generate CSRF protection state
state = secrets.token_urlsafe(32)
# VULNERABLE - OAuth state cookie without Secure flag
response = make_response(redirect(
f'https://oauth.provider.com/authorize?'
f'client_id=YOUR_CLIENT_ID&'
f'redirect_uri=https://example.com/oauth/callback&'
f'state={state}'
))
response.set_cookie(
'oauth_state',
state,
max_age=600 # 10 minutes
# Missing: secure=True, httponly=True, samesite
)
return response
@app.route('/oauth/callback')
def oauth_callback():
state_param = request.args.get('state')
state_cookie = request.cookies.get('oauth_state')
if state_param != state_cookie:
return {'error': 'Invalid state'}, 400
# Continue OAuth flow
return {'status': 'success'}
Why this is vulnerable:
- OAuth state token exposed over HTTP
- CSRF protection compromised
- Enables OAuth token theft
- OAuth security model broken
Bottle Framework Without Secure Cookies
# VULNERABLE - Bottle application with insecure cookies
from bottle import Bottle, request, response
import secrets
app = Bottle()
@app.post('/login')
def login():
username = request.forms.get('username')
password = request.forms.get('password')
if authenticate_user(username, password):
session_id = secrets.token_hex(32)
# VULNERABLE - Bottle cookie without secure flag
response.set_cookie(
'session_id',
session_id,
max_age=3600,
httponly=True
# Missing: secure=True
)
return {'status': 'logged_in'}
return {'error': 'Invalid credentials'}
def authenticate_user(username, password):
return True
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
Why this is vulnerable:
- Bottle framework requires explicit
secure=True - Cookie transmitted over HTTP
- Session hijacking possible
- Framework default is insecure
Pyramid Framework Without Secure Cookies
# VULNERABLE - Pyramid session without secure cookies
from pyramid.config import Configurator
from pyramid.view import view_config
from pyramid.response import Response
import secrets
@view_config(route_name='login', request_method='POST', renderer='json')
def login_view(request):
username = request.POST.get('username')
password = request.POST.get('password')
if authenticate_user(username, password):
session_token = secrets.token_hex(32)
# VULNERABLE - Pyramid cookie without secure flag
response = Response(json_body={'status': 'logged_in'})
response.set_cookie(
'session_id',
session_token,
max_age=3600,
httponly=True
# Missing: secure=True
)
return response
return Response(json_body={'error': 'Invalid credentials'}, status=401)
def authenticate_user(username, password):
return True
def main(global_config, **settings):
config = Configurator(settings=settings)
config.add_route('login', '/login')
config.scan()
return config.make_wsgi_app()
Why this is vulnerable:
- Pyramid sessions exposed
- No secure flag protection
- Production deployment risk
- Framework misconfiguration
Secure Patterns
Flask Cookie With All Security Flags
# SECURE - Flask cookie with proper security flags
from flask import Flask, request, make_response
import secrets
from datetime import timedelta
app = Flask(__name__)
# SECURE - Configure session cookie security
app.config.update(
SESSION_COOKIE_SECURE=True,
SESSION_COOKIE_HTTPONLY=True,
SESSION_COOKIE_SAMESITE='Strict',
PERMANENT_SESSION_LIFETIME=timedelta(hours=1)
)
@app.route('/login', methods=['POST'])
def secure_login():
username = request.form.get('username')
password = request.form.get('password')
if authenticate_user(username, password):
session_token = secrets.token_hex(32)
response = make_response({'status': 'logged_in'})
# SECURE - All critical security flags set
response.set_cookie(
'session_id',
session_token,
secure=True, # Only sent over HTTPS
httponly=True, # Not accessible via JavaScript
samesite='Strict', # CSRF protection
max_age=3600 # 1 hour expiration
)
return response
return {'error': 'Invalid credentials'}, 401
def authenticate_user(username, password):
# Secure authentication logic
return True
if __name__ == '__main__':
# SECURE - Only run on HTTPS in production
# Use a proper WSGI server (gunicorn, uWSGI) with TLS
app.run(ssl_context='adhoc') # For development only
Why this works:
- Secure/HttpOnly/SameSite enforce HTTPS-only cookies and block XSS/CSRF.
- App-wide config applies flags consistently to all session cookies.
- Short lifetimes and strong tokens limit exposure.
Django With Proper Cookie Security
# settings.py - SECURE configuration
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['example.com', 'www.example.com']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
]
# SECURE - Session cookie security settings
SESSION_COOKIE_SECURE = True # Only send over HTTPS
SESSION_COOKIE_HTTPONLY = True # Not accessible via JavaScript
SESSION_COOKIE_SAMESITE = 'Strict' # CSRF protection
SESSION_COOKIE_AGE = 3600 # 1 hour
# SECURE - CSRF cookie security
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_SAMESITE = 'Strict'
# SECURE - Additional security settings
SECURE_SSL_REDIRECT = True # Redirect HTTP to HTTPS
SECURE_HSTS_SECONDS = 31536000 # HTTP Strict Transport Security
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
# views.py
from django.contrib.auth import authenticate, login
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import ensure_csrf_cookie
@require_http_methods(["POST"])
def secure_login(request):
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
# SECURE - Django automatically applies SESSION_COOKIE_SECURE
login(request, user)
return JsonResponse({'status': 'logged_in'})
return JsonResponse({'error': 'Invalid credentials'}, status=401)
@ensure_csrf_cookie
def get_csrf_token(request):
# SECURE - CSRF token sent with secure flag
return JsonResponse({'csrfToken': 'set_in_cookie'})
Why this works:
- App-wide settings enforce Secure/HttpOnly/SameSite on session and CSRF cookies.
- HTTPS redirect + HSTS prevent downgrade and plaintext transport.
- Short session age limits exposure.
FastAPI With Secure Cookies
# SECURE - FastAPI with proper cookie security
from fastapi import FastAPI, Response, Request, HTTPException, Depends
from fastapi.responses import JSONResponse
from fastapi.security import HTTPBearer
from pydantic import BaseModel
import secrets
from datetime import datetime, timedelta
from typing import Optional
app = FastAPI()
# In-memory session store (use Redis in production)
sessions = {}
class LoginRequest(BaseModel):
username: str
password: str
security = HTTPBearer()
def get_current_user(request: Request):
"""Dependency to validate session"""
session_token = request.cookies.get("session_token")
if not session_token or session_token not in sessions:
raise HTTPException(status_code=401, detail="Not authenticated")
session = sessions[session_token]
# Check expiration
if datetime.now() > session['expires_at']:
del sessions[session_token]
raise HTTPException(status_code=401, detail="Session expired")
return session['username']
@app.post("/login")
async def secure_login(request: LoginRequest, response: Response):
if authenticate_user(request.username, request.password):
session_token = secrets.token_urlsafe(32)
# Store session with expiration
sessions[session_token] = {
'username': request.username,
'created_at': datetime.now(),
'expires_at': datetime.now() + timedelta(hours=1)
}
# SECURE - All security flags set
response.set_cookie(
key="session_token",
value=session_token,
secure=True, # HTTPS only
httponly=True, # Not accessible via JavaScript
samesite="strict", # CSRF protection
max_age=3600 # 1 hour
)
return {"status": "logged_in"}
raise HTTPException(status_code=401, detail="Invalid credentials")
@app.post("/logout")
async def logout(request: Request, response: Response):
session_token = request.cookies.get("session_token")
if session_token and session_token in sessions:
del sessions[session_token]
# Delete cookie
response.delete_cookie(
key="session_token",
secure=True,
httponly=True,
samesite="strict"
)
return {"status": "logged_out"}
@app.get("/protected")
async def protected_route(username: str = Depends(get_current_user)):
return {"message": f"Hello {username}", "protected": True}
def authenticate_user(username: str, password: str) -> bool:
# Secure authentication logic
return True
if __name__ == "__main__":
import uvicorn
# SECURE - Run with TLS in production
uvicorn.run(
app,
host="0.0.0.0",
port=8443,
ssl_keyfile="path/to/key.pem",
ssl_certfile="path/to/cert.pem"
)
Why this works:
- Secure/HttpOnly/SameSite enforce HTTPS-only cookies and block XSS/CSRF.
- Expiration checks and logout cleanup invalidate stolen tokens quickly.
- TLS config + strong tokens reduce interception and guessing risk.
Secure Remember-Me Implementation
# SECURE - Remember-me with proper security
from flask import Flask, request, make_response
import secrets
import hashlib
from datetime import datetime, timedelta
import os
app = Flask(__name__)
# SECURE - App configuration
app.config.update(
SESSION_COOKIE_SECURE=True,
SESSION_COOKIE_HTTPONLY=True,
SESSION_COOKIE_SAMESITE='Strict',
REMEMBER_COOKIE_SECURE=True,
REMEMBER_COOKIE_HTTPONLY=True,
REMEMBER_COOKIE_DURATION=timedelta(days=30)
)
class RememberMeToken:
"""Secure remember-me token management"""
@staticmethod
def generate_token():
"""Generate cryptographically secure token"""
return secrets.token_urlsafe(64)
@staticmethod
def hash_token(token):
"""Hash token for storage"""
return hashlib.sha256(token.encode()).hexdigest()
@staticmethod
def store_token(username, token):
"""Store hashed token in database"""
token_hash = RememberMeToken.hash_token(token)
# Store in database with expiration
db.remember_tokens.insert({
'username': username,
'token_hash': token_hash,
'created_at': datetime.now(),
'expires_at': datetime.now() + timedelta(days=30)
})
@staticmethod
def verify_token(token):
"""Verify remember-me token"""
token_hash = RememberMeToken.hash_token(token)
token_record = db.remember_tokens.find_one({
'token_hash': token_hash,
'expires_at': {'$gt': datetime.now()}
})
if token_record:
return token_record['username']
return None
@app.route('/login', methods=['POST'])
def login_with_remember():
username = request.form.get('username')
password = request.form.get('password')
remember_me = request.form.get('remember_me') == 'true'
if authenticate_user(username, password):
session_token = secrets.token_hex(32)
response = make_response({'status': 'logged_in'})
# SECURE - Session cookie with all flags
response.set_cookie(
'session_id',
session_token,
secure=True,
httponly=True,
samesite='Strict',
max_age=3600
)
if remember_me:
remember_token = RememberMeToken.generate_token()
RememberMeToken.store_token(username, remember_token)
# SECURE - Remember-me cookie with all flags
response.set_cookie(
'remember_me',
remember_token,
secure=True, # HTTPS only
httponly=True, # Not accessible via JavaScript
samesite='Strict', # CSRF protection
max_age=30*24*3600 # 30 days
)
return response
return {'error': 'Invalid credentials'}, 401
@app.route('/auto-login', methods=['POST'])
def auto_login():
"""Auto-login using remember-me token"""
remember_token = request.cookies.get('remember_me')
if not remember_token:
return {'error': 'No remember-me token'}, 401
username = RememberMeToken.verify_token(remember_token)
if username:
session_token = secrets.token_hex(32)
response = make_response({'status': 'auto_logged_in', 'username': username})
# SECURE - Create new session
response.set_cookie(
'session_id',
session_token,
secure=True,
httponly=True,
samesite='Strict',
max_age=3600
)
return response
return {'error': 'Invalid token'}, 401
def authenticate_user(username, password):
return True
# Mock database
class MockDB:
def __init__(self):
self.remember_tokens = MockCollection()
class MockCollection:
def __init__(self):
self.data = []
def insert(self, doc):
self.data.append(doc)
def find_one(self, query):
# Simple mock implementation
return None
db = MockDB()
Why this works:
- Secure/HttpOnly/SameSite protect both session and remember-me cookies.
- Tokens are hashed at rest and expire, limiting replay and DB compromise impact.
- Auto-login issues a fresh short-lived session cookie.
JWT Cookie With Proper Security
# SECURE - JWT in cookie with all security flags
from flask import Flask, request, make_response
import jwt
from datetime import datetime, timedelta
import os
app = Flask(__name__)
# SECURE - Use environment variable for secret
JWT_SECRET = os.environ.get('JWT_SECRET_KEY')
if not JWT_SECRET:
raise ValueError("JWT_SECRET_KEY environment variable not set")
@app.route('/api/login', methods=['POST'])
def secure_api_login():
username = request.json.get('username')
password = request.json.get('password')
if authenticate_user(username, password):
# Create JWT with expiration
payload = {
'username': username,
'iat': datetime.utcnow(),
'exp': datetime.utcnow() + timedelta(hours=1)
}
token = jwt.encode(payload, JWT_SECRET, algorithm='HS256')
response = make_response({'status': 'success'})
# SECURE - All security flags set
response.set_cookie(
'auth_token',
token,
secure=True, # HTTPS only
httponly=True, # Not accessible via JavaScript
samesite='Strict', # CSRF protection
max_age=3600 # 1 hour
)
return response
return {'error': 'Authentication failed'}, 401
@app.route('/api/protected', methods=['GET'])
def protected_api():
auth_token = request.cookies.get('auth_token')
if not auth_token:
return {'error': 'Not authenticated'}, 401
try:
# Verify JWT
payload = jwt.decode(
auth_token,
JWT_SECRET,
algorithms=['HS256']
)
return {
'message': f'Hello {payload["username"]}',
'protected': True
}
except jwt.ExpiredSignatureError:
return {'error': 'Token expired'}, 401
except jwt.InvalidTokenError:
return {'error': 'Invalid token'}, 401
def authenticate_user(username, password):
return True
Why this works:
- Secure/HttpOnly/SameSite cookies protect JWTs from XSS/CSRF and HTTP leakage.
- Expiration is enforced by both cookie max-age and JWT
exp. - Secret management via env vars prevents hardcoded secrets.
OAuth State Cookie With Security
# SECURE - OAuth state cookie with proper security
from flask import Flask, request, redirect, make_response, session
import secrets
import os
app = Flask(__name__)
app.secret_key = os.environ.get('FLASK_SECRET_KEY')
# SECURE - Configure session security
app.config.update(
SESSION_COOKIE_SECURE=True,
SESSION_COOKIE_HTTPONLY=True,
SESSION_COOKIE_SAMESITE='Lax' # Lax for OAuth redirects
)
OAUTH_CLIENT_ID = os.environ.get('OAUTH_CLIENT_ID')
OAUTH_CLIENT_SECRET = os.environ.get('OAUTH_CLIENT_SECRET')
@app.route('/oauth/authorize')
def oauth_authorize():
# Generate CSRF protection state
state = secrets.token_urlsafe(32)
# Store state in session (automatically uses secure cookies)
session['oauth_state'] = state
session['oauth_initiated_at'] = datetime.now().isoformat()
# Build OAuth URL
oauth_url = (
f'https://oauth.provider.com/authorize?'
f'client_id={OAUTH_CLIENT_ID}&'
f'redirect_uri=https://example.com/oauth/callback&'
f'response_type=code&'
f'state={state}&'
f'scope=read:user'
)
return redirect(oauth_url)
@app.route('/oauth/callback')
def oauth_callback():
state_param = request.args.get('state')
state_session = session.get('oauth_state')
initiated_at = session.get('oauth_initiated_at')
# Verify state parameter
if not state_param or state_param != state_session:
return {'error': 'Invalid state parameter'}, 400
# Check state age (prevent replay)
if initiated_at:
initiated_time = datetime.fromisoformat(initiated_at)
if datetime.now() - initiated_time > timedelta(minutes=10):
return {'error': 'State expired'}, 400
# Clear state from session
session.pop('oauth_state', None)
session.pop('oauth_initiated_at', None)
# Exchange code for token
code = request.args.get('code')
# Continue OAuth flow...
return {'status': 'success'}
from datetime import datetime, timedelta
Why this works:
- OAuth state is stored in a secure session cookie (Lax for redirects).
- State validation + short expiration block CSRF and replay.
- Single-use cleanup and strong state tokens reduce abuse.
Verification
After implementing the recommended secure patterns, verify the fix through multiple approaches:
- Manual testing: Submit malicious payloads relevant to this vulnerability and confirm they're handled safely without executing unintended operations
- Code review: Confirm all instances use the secure pattern (parameterized queries, safe APIs, proper encoding) with no string concatenation or unsafe operations
- Static analysis: Use security scanners to verify no new vulnerabilities exist and the original finding is resolved
- Regression testing: Ensure legitimate user inputs and application workflows continue to function correctly
- Edge case validation: Test with special characters, boundary conditions, and unusual inputs to verify proper handling
- Framework verification: If using a framework or library, confirm the recommended APIs are used correctly according to documentation
- Authentication/session testing: Verify security controls remain effective and cannot be bypassed (if applicable to the vulnerability type)
- Rescan: Run the security scanner again to confirm the finding is resolved and no new issues were introduced