Skip to main content
Glama
session_management.yaml10.4 kB
# OWASP ASVS v4.0 - Chapter 3: Session Management requirements: - id: "3.1.1" level: 1 category: "Fundamental Session Management" requirement: "Verify the application never reveals session tokens in URL parameters or error messages." cwe: "CWE-598" description: | Session tokens in URLs can be logged in browser history, proxy logs, and referrer headers, exposing them to attackers. implementation_guide: | - Always use cookies or HTTP headers for session tokens - Never pass session IDs as URL parameters (?sessionid=xxx) - Use HTTP-only cookies to prevent JavaScript access - Ensure error messages don't include session tokens - Review all logging to ensure sessions aren't logged code_examples: - | # Python Flask - GOOD from flask import session @app.route('/dashboard') def dashboard(): user_id = session.get('user_id') # Session in cookie if not user_id: return redirect('/login') return render_template('dashboard.html') # BAD - Don't do this! @app.route('/dashboard') def dashboard_bad(): session_id = request.args.get('session') # NEVER DO THIS # ... - id: "3.2.1" level: 1 category: "Session Binding" requirement: "Verify the application generates a new session token on user authentication." cwe: "CWE-384" description: | Generate a new session ID after successful login to prevent session fixation attacks. This ensures any pre-existing session cannot be hijacked. implementation_guide: | - Generate new session ID immediately after successful authentication - Invalidate the old session ID - Regenerate session on privilege level changes - Clear all session data and create fresh session code_examples: - | # Python Flask from flask import session @app.route('/login', methods=['POST']) def login(): username = request.form['username'] password = request.form['password'] if verify_credentials(username, password): # Clear old session session.clear() # Regenerate session ID session.regenerate() # Set new session data session['user_id'] = get_user_id(username) session['authenticated'] = True return redirect('/dashboard') - | # Express.js app.post('/login', (req, res) => { const { username, password } = req.body; if (verifyCredentials(username, password)) { // Regenerate session req.session.regenerate((err) => { if (err) return res.status(500).json({ error: 'Session error' }); req.session.userId = getUserId(username); req.session.authenticated = true; res.redirect('/dashboard'); }); } }); - id: "3.2.2" level: 1 category: "Session Binding" requirement: "Verify that session tokens possess at least 64 bits of entropy." cwe: "CWE-331" description: | Session tokens must be cryptographically random with sufficient entropy to prevent brute force attacks. implementation_guide: | - Use cryptographically secure random number generator - Generate at least 64 bits (8 bytes) of entropy - Recommended: 128 bits (16 bytes) or more - Use framework's built-in session management (usually secure by default) code_examples: - | # Python import secrets def generate_session_token() -> str: """Generate cryptographically secure session token with 128 bits entropy.""" return secrets.token_urlsafe(16) # 16 bytes = 128 bits def generate_session_hex() -> str: """Alternative: hex token with 128 bits entropy.""" return secrets.token_hex(16) # 16 bytes = 32 hex chars - id: "3.3.1" level: 1 category: "Session Logout and Timeout" requirement: "Verify that logout and expiration invalidate the session token, such that the back button or a downstream relying party does not resume an authenticated session." cwe: "CWE-613" description: | When users log out, their session must be completely invalidated server-side to prevent session reuse. implementation_guide: | - Delete session from server-side storage on logout - Clear session cookie with proper flags - Implement session timeout for inactive sessions - Don't rely solely on client-side cookie deletion - Redirect to login page after logout code_examples: - | # Python Flask @app.route('/logout', methods=['POST']) def logout(): # Clear session server-side session_id = session.get('session_id') if session_id: delete_session_from_database(session_id) # Clear session data session.clear() # Clear cookie response = make_response(redirect('/login')) response.set_cookie('session', '', expires=0) return response - id: "3.3.2" level: 1 category: "Session Logout and Timeout" requirement: "Verify that the application gives the option to terminate all other active sessions after a successful password change or account compromise." cwe: "CWE-613" description: | Users should be able to terminate all active sessions, especially after password change or suspected compromise. implementation_guide: | - Store all active sessions per user in database - Provide UI to view active sessions - Allow users to terminate individual or all sessions - Automatically terminate other sessions on password change - Show session details (device, location, last activity) code_examples: - | # Python def terminate_all_user_sessions(user_id: int, except_current: bool = True) -> int: """Terminate all sessions for a user.""" current_session_id = session.get('session_id') # Get all user sessions user_sessions = get_user_sessions(user_id) terminated = 0 for sess in user_sessions: if except_current and sess.id == current_session_id: continue # Delete from session store delete_session(sess.id) terminated += 1 return terminated @app.route('/change-password', methods=['POST']) def change_password(): user_id = session.get('user_id') new_password = request.form['new_password'] # Update password update_user_password(user_id, new_password) # Terminate all other sessions terminate_all_user_sessions(user_id, except_current=True) return jsonify({'message': 'Password changed, other sessions terminated'}) - id: "3.4.1" level: 1 category: "Cookie-based Session Management" requirement: "Verify that cookie-based session tokens have the 'Secure' attribute set." cwe: "CWE-614" description: | The Secure flag ensures cookies are only sent over HTTPS, preventing interception over unencrypted connections. implementation_guide: | - Set Secure flag on all session cookies - Only allow cookies over HTTPS in production - Configure web framework session settings - Test that cookies aren't sent over HTTP code_examples: - | # Python Flask app.config['SESSION_COOKIE_SECURE'] = True app.config['SESSION_COOKIE_HTTPONLY'] = True app.config['SESSION_COOKIE_SAMESITE'] = 'Lax' - | # Express.js app.use(session({ secret: process.env.SESSION_SECRET, cookie: { secure: true, // Only send over HTTPS httpOnly: true, // Not accessible via JavaScript sameSite: 'lax', // CSRF protection maxAge: 3600000 // 1 hour } })); - id: "3.4.2" level: 1 category: "Cookie-based Session Management" requirement: "Verify that cookie-based session tokens have the 'HttpOnly' attribute set." cwe: "CWE-1004" description: | The HttpOnly flag prevents JavaScript from accessing the cookie, mitigating XSS attacks that attempt to steal session tokens. implementation_guide: | - Set HttpOnly flag on all session cookies - This prevents document.cookie access in JavaScript - Essential defense-in-depth against XSS - Should be enabled by default in most frameworks code_examples: - | # Python Flask app.config['SESSION_COOKIE_HTTPONLY'] = True # Or set manually: response = make_response(render_template('page.html')) response.set_cookie( 'session', session_token, httponly=True, secure=True, samesite='Lax' ) - id: "3.4.5" level: 1 category: "Cookie-based Session Management" requirement: "Verify that cookie-based session tokens utilize the 'SameSite' attribute to limit exposure to cross-site request forgery attacks." cwe: "CWE-352" description: | SameSite attribute prevents cookies from being sent with cross-site requests, providing CSRF protection. implementation_guide: | - Use SameSite=Lax for most applications (balances security and usability) - Use SameSite=Strict for high-security applications (may break some flows) - Don't use SameSite=None unless absolutely necessary (e.g., embedded iframes) - Combine with CSRF tokens for defense-in-depth code_examples: - | # Python Flask app.config['SESSION_COOKIE_SAMESITE'] = 'Lax' # For high security: app.config['SESSION_COOKIE_SAMESITE'] = 'Strict'

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/harn1shmodi/vsguard-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server