HIGH broken authenticationflaskbearer tokens

Broken Authentication in Flask with Bearer Tokens

Broken Authentication in Flask with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Broken Authentication in Flask when using Bearer Tokens typically arises from misconfiguration and insecure handling of token transmission, storage, and validation. Flask itself is minimal and does not enforce authentication; developers add behavior by integrating token-based mechanisms such as bearer tokens. If tokens are transmitted over unencrypted channels, stored insecurely, or validated with weak logic, the authentication boundary breaks.

One common pattern is defining a route that reads an Authorization header and trusts a static or predictable token. For example:

from flask import Flask, request, jsonify

app = Flask(__name__)

# Insecure: static bearer token, no transport or storage protections
VALID_TOKEN = 'secret123'

@app.route('/profile')
def profile():
    auth = request.headers.get('Authorization', '')
    if auth.startswith('Bearer ') and auth.split(' ')[1] == VALID_TOKEN:
        return jsonify(user='alice', role='admin')
    return jsonify(error='Unauthorized'), 401

if __name__ == '__main__':
    app.run(debug=True)  # Debug mode can expose tokens in error pages

This approach is vulnerable because the token is hardcoded and equivalent to a shared secret; if leaked, an attacker can impersonate any user. Transport weaknesses occur when the token is sent over HTTP rather than HTTPS, enabling on-path interception. Storage flaws arise if tokens are logged, cached, or persisted in client-side storage without adequate protection. Validation weaknesses include accepting any string as a bearer token without verifying scope, revocation, or cryptographic integrity, making token replay or tampering feasible.

Another vulnerability pattern involves insufficient scope checks after authentication. An API may issue a bearer token but fail to enforce per-endpoint authorization, allowing a token with read-only permissions to execute privileged actions. This is often a symptom of missing or misconfigured authorization tied to the authentication layer. Additionally, tokens with long lifetimes increase the window for abuse if they are stolen. Without short expiration, revocation mechanisms, or binding to a particular client context, the authentication boundary remains fragile.

Middleware or proxy configurations can inadvertently weaken bearer token security. For instance, terminating TLS at a load balancer while forwarding requests to Flask over HTTP may expose headers, including the Authorization header, to internal networks. Flask applications must validate that tokens are only accepted over secure channels and that internal routing preserves integrity. Without explicit enforcement, the framework’s minimal defaults do not protect against these deployment-level risks.

Insecure deserialization or improper parsing of the Authorization header can also lead to authentication bypass. For example, an implementation that splits on spaces and takes the second element without strict validation may accept malformed inputs or multiple bearer-like strings. Attackers can craft ambiguous headers to bypass intended checks. Robust implementations should strictly parse the scheme, reject malformed inputs, and avoid custom token formats that deviate from standards.

Bearer Tokens-Specific Remediation in Flask — concrete code fixes

Remediation focuses on secure transmission, proper validation, scope enforcement, and operational hygiene. Always serve Flask over HTTPS using a trusted TLS termination point, and ensure the Authorization header is never logged or exposed in error messages. Prefer standard token formats (e.g., JWT) with verifiable signatures instead of static bearer strings.

Use environment variables for secrets and validate token structure rigorously. Below is a more secure example using bearer tokens with JWT verification:

import os
import jwt
from flask import Flask, request, jsonify

app = Flask(__name__)
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
SEVER_PUBLIC_KEY = os.environ.get('PUBLIC_KEY')

@app.route('/profile')
def profile():
    auth = request.headers.get('Authorization', '')
    if not auth.startswith('Bearer '):
        return jsonify(error='Unauthorized'), 401
    token = auth.split(' ')[1]
    try:
        payload = jwt.decode(token, PUBLIC_KEY, algorithms=['RS256'], audience='api', issuer='auth-service')
        # Enforce scope for this endpoint
        if 'read:profile' not in payload.get('scope', '').split():
            return jsonify(error='Insufficient scope'), 403
        return jsonify(user=payload.get('sub'), role=payload.get('role'))
    except jwt.ExpiredSignatureError:
        return jsonify(error='Token expired'), 401
    except jwt.InvalidTokenError:
        return jsonify(error='Invalid token'), 401

if __name__ == '__main__':
    # In production, use a WSGI server and TLS termination at the edge
    app.run(ssl_context='adhoc')  # adhoc仅用于演示;生产环境应使用可信证书

This approach validates the token signature, checks audience and issuer, and enforces scope-based authorization. Environment variables keep secrets out of source code, and JWT expiration reduces the impact of token leakage. For non-JWT bearer tokens, store token hashes in a server-side revocation list and validate against it on each request.

Implement short token lifetimes and refresh workflows to limit exposure. Use HTTP-only, Secure cookies for refresh tokens if browser clients are involved, and avoid embedding bearer tokens in URLs. Apply consistent security headers and ensure logging practices exclude Authorization header values. Regularly rotate signing keys and monitor for anomalous usage patterns to detect compromised tokens early.

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

Why is hardcoding a bearer token in Flask code considered a critical risk?
Hardcoding a bearer token creates a shared secret that, if discovered, grants unrestricted access. It prevents rotation, lacks binding to a specific identity or scope, and often bypasses proper validation and revocation mechanisms, leading to authentication bypass.
How does middleBrick handle Bearer Token security checks?
middleBrick scans unauthenticated attack surfaces and includes checks for Authentication and Authorization mechanisms. It assesses token transmission, validation logic, and scope enforcement, mapping findings to frameworks like OWASP API Top 10 and providing prioritized remediation guidance.