HIGH session fixationflaskbasic auth

Session Fixation in Flask with Basic Auth

Session Fixation in Flask with Basic Auth — how this specific combination creates or exposes the vulnerability

Session fixation occurs when an application assigns a user a session identifier (session ID) before authentication and does not issue a new identifier after login. In Flask, this commonly happens when a session cookie is created before the user provides credentials and the same cookie is reused after authentication. When Basic Auth is used, the client sends username and base64‑encoded credentials with every request via the Authorization header. Because Basic Auth lacks a built‑in session mechanism, developers often implement session handling on top of it—typically by storing user identity in Flask’s session after successful authentication. If the session ID was issued before authentication and is never regenerated after login, an attacker who knows or fixes the session ID can trick a victim into authenticating under that known session, then use the session ID to impersonate the victim.

Consider a Flask route that checks for an authenticated user via a session key but only validates credentials on initial login:

from flask import Flask, request, session, redirect, url_for
import base64

app = Flask(__name__)
app.secret_key = 'super-secret-key'  # must be strong and kept server-side

@app.route('/login', methods=['POST'])
def login():
    auth = request.headers.get('Authorization', '')
    if not auth.lower().startswith('basic '):
        return 'Missing Basic Auth', 401
    try:
        _, encoded = auth.split(' ', 1)
        decoded = base64.b64decode(encoded).decode('utf-8')
        username, password = decoded.split(':', 1)
        # naive credential check
        if username == 'alice' and password == 'secret':
            session['user'] = username
            return 'Logged in'
        return 'Invalid credentials', 401
    except Exception:
        return 'Invalid auth header', 400

In this pattern, if the victim’s browser already has a session cookie (set before login), logging in does not change the session ID. An attacker can craft a link such as https://example.com/login that the victim visits while already identified by a known session cookie. After the victim submits credentials, the session key remains the same, and the attacker can use that session cookie to access authenticated endpoints as the victim. This meets the OWASP API Top 10 session management concerns and aligns with common authentication bypass patterns where identity is tied to an unrotated session.

Additionally, because Basic Auth sends credentials in every request, session tokens stored in cookies can be at risk if transmitted over unencrypted channels. Without TLS, both the Authorization header and the session cookie are exposed, enabling network interception that compounds fixation with eavesdropping. Even with TLS, if the session cookie lacks secure flags and proper SameSite settings, the attack surface remains wide. The scanner’s checks, such as those under Data Exposure and Encryption, can surface missing transport protections that exacerbate fixation risks.

Basic Auth-Specific Remediation in Flask — concrete code fixes

To mitigate session fixation in Flask with Basic Auth, ensure a new session is created after successful authentication and enforce transport security. The key remediation steps are: (1) always regenerate the session identifier on login, (2) require HTTPS in production, and (3) apply secure cookie attributes. Below is a secure implementation that incorporates these practices.

from flask import Flask, request, session, redirect, url_for, make_response
import base64

app = Flask(__name__)
app.secret_key = 'super-secret-key'  # rotate and protect this key

@app.route('/login', methods=['POST'])
def login():
    auth = request.headers.get('Authorization', '')
    if not auth.lower().startswith('basic '):
        return 'Missing Basic Auth', 401
    try:
        _, encoded = auth.split(' ', 1)
        decoded = base64.b64decode(encoded).decode('utf-8')
        username, password = decoded.split(':', 1)
        if username == 'alice' and password == 'secret':
            # Regenerate session to prevent fixation
            session.clear()
            session['user'] = username
            # Optionally, rotate session further via session.modified
            response = make_response('Logged in')
            # Enforce Secure; in dev you may omit, but never in prod
            response.set_cookie('session', session.signed_cookie(), httponly=True, secure=True, samesite='Lax')
            return response
        return 'Invalid credentials', 401
    except Exception:
        return 'Invalid auth header', 400

Key points in this code:

  • session.clear() removes any pre‑login session data and, combined with Flask’s session management, issues a new session identifier, effectively mitigating fixation.
  • secure=True ensures the cookie is only sent over HTTPS, protecting against passive network sniffing when used in production.
  • httponly=True reduces exposure to client‑side script access, lowering the risk of session theft via XSS.
  • samesite='Lax' helps mitigate cross‑site request forgery (CSRF) alongside other defenses.

In CI/CD workflows, you can integrate middleBrick’s GitHub Action to ensure that any regression in authentication or session handling fails the build if the scanner detects insecure configurations or missing transport protections. For continuous monitoring, the Pro plan provides scheduled scans and alerts so that new endpoints or changes do not reintroduce fixation risks.

Frequently Asked Questions

Why does session fixation still matter when using Basic Auth with HTTPS?
Even with HTTPS, if the session ID is assigned before authentication and never regenerated, an attacker can force a victim to authenticate under a known session. HTTPS protects credential transmission but does not prevent session fixation; explicit session regeneration on login is required.
Does middleBrick detect session fixation in Flask APIs using Basic Auth?
middleBrick runs 12 security checks in parallel, including checks relevant to authentication and session handling. While the scanner reports findings and provides remediation guidance, it does not fix or block issues; developers must apply the suggested code changes to address session fixation.