Broken Authentication

Broken Authentication in Flask Remediation [Apr 2026] [CVE-2026-34531]

[Fixed Apr 2026] Updated CVE-2026-34531

Overview

This guide discusses CVE-2026-34531 in Flask-HTTPAuth, which caused a Broken Authentication risk in applications that protected endpoints with token-based access. Prior to version 4.8.1, when a client requested a token-protected resource without providing a token or with an empty token, Flask-HTTPAuth could invoke the application's token verification callback with token set to an empty string. If the application stored any user with an empty token, authentication could succeed against that user, effectively bypassing authorization for legitimate users. The issue highlights how lax handling of missing or empty tokens in the verification flow can create broad access if the token store contains empty values. The problem was patched in version 4.8.1, but any deployments using older releases are at risk and should verify their verification logic and token policies. This vulnerability maps to CWE-287 (Improper Authentication). In Flask apps using Basic, Digest or Token authentication via Flask-HTTPAuth, an empty or missing token must be treated as invalid and never allowed to verify a user.

Affected Versions

< 4.8.1

Code Fix Example

Flask API Security Remediation
# Vulnerable pattern
from flask import Flask
from flask_httpauth import HTTPTokenAuth

app = Flask(__name__)
auth = HTTPTokenAuth(scheme='Bearer')

# Simulated user store with an empty token
tokens = {'alice': 'token123', 'bob': ''}

@auth.verify_token
def verify_token(token):
    # Vulnerable: this will return True for token == '' if '' is stored in tokens.values()
    return token in tokens.values()

@app.route('/protected')
@auth.login_required
def protected():
    return 'secret'

# Fixed version (concrete guard against empty tokens)
app2 = Flask(__name__)
auth2 = HTTPTokenAuth(scheme='Bearer')

@auth2.verify_token
def verify_token_fixed(token):
    # Fix: reject missing or empty tokens explicitly
    if not token or not token.strip():
        return False
    return token in tokens.values()

@app2.route('/protected')
@auth2.login_required
def protected_fixed():
    return 'secret'

# Note: In a real application, you would run one app instance per process; this snippet demonstrates both patterns for comparison.

CVE References

Choose which optional cookies to allow. You can change this any time.