HIGH broken authenticationflaskbasic auth

Broken Authentication in Flask with Basic Auth

Broken Authentication in Flask with Basic Auth — how this specific combination creates or exposes the vulnerability

Using HTTP Basic Authentication in Flask without additional protections is a common source of Broken Authentication issues. Basic Auth sends credentials in an Authorization header that is base64-encoded but not encrypted, so any party on the network path that can observe the request can decode the credentials. In Flask, developers sometimes implement Basic Auth manually with decorators and helpers, and if they skip transport-layer protections or reuse the same credentials across environments, the attack surface expands.

One typical pattern that leads to vulnerability is a custom check_auth function that validates a hardcoded username and password without rate limiting or secure credential storage. For example:

from flask import Flask, request, Response
import base64

app = Flask(__name__)

def check_auth(username, password):
    return username == 'admin' and password == 'secret123'

def authenticate():
    return Response(
        'Could not verify your access level for URL: %s' % request.url,
        401,
        {'WWW-Authenticate': 'Basic realm="Login Required"'}
    )

@app.route('/admin')
def admin_page():
    auth = request.authorization
    if not auth or not check_auth(auth.username, auth.password):
        return authenticate()
    return 'Admin Panel: Top secret data'

if __name__ == '__main__':
    app.run(debug=True)

This example highlights multiple risk factors: the credentials are hardcoded and compared in plaintext, debugging is enabled for the Flask app, and there is no enforcement of HTTPS. When Basic Auth is used over HTTP, credentials are trivial to intercept. Even over HTTPS, additional concerns remain, such as the lack of account lockout after repeated failures, which makes brute-force attacks feasible. Because middleBrick scans the unauthenticated attack surface, it can detect endpoints that expose admin routes with Basic Auth and flag weak or missing protections as a Broken Authentication finding.

Additionally, when the same credentials are reused across multiple environments (development, staging, production), a leaked credential from a less-protected environment can lead to unauthorized access in production. Without multi-factor authentication or session management, Basic Auth provides no mechanism for revocation beyond changing the hardcoded password. This aligns with the Broken Authentication category in the OWASP API Top 10 and can result in sensitive data exposure or privilege escalation.

middleBrick’s 12 security checks run in parallel and can identify endpoints using Basic Auth over unencrypted channels, missing rate limiting, and weak authorization boundaries. The scanner correlates these findings with the OpenAPI spec when available, helping teams understand how authentication mechanisms map to declared routes and operations.

Basic Auth-Specific Remediation in Flask — concrete code fixes

To address Broken Authentication when using Basic Auth in Flask, you should enforce HTTPS, avoid hardcoded credentials, and integrate with secure credential stores. Below is a revised implementation that mitigates the most common risks.

First, always require HTTPS in production. You can enforce this in Flask using a before-request hook and a trusted proxy setup at the load balancer or reverse proxy:

from flask import Flask, request, Response
from functools import wraps
import os

app = Flask(__name__)

def require_https(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        if not request.is_secure:
            return 'HTTPS required', 403
        return f(*args, **kwargs)
    return decorated

app.before_request(require_https)

Second, use environment variables or a secrets manager instead of hardcoding credentials. For example, load credentials from environment variables and compare them securely:

import os
from werkzeug.security import generate_password_hash, check_password_hash

ADMIN_USER = os.environ.get('ADMIN_USER')
ADMIN_PASS_HASH = os.environ.get('ADMIN_PASS_HASH')

def check_auth(username, password):
    if not ADMIN_USER or not ADMIN_PASS_HASH:
        return False
    return username == ADMIN_USER and check_password_hash(ADMIN_PASS_HASH, password)

Generate the hash once with Python and store it in your environment:

from werkzeug.security import generate_password_hash
print(generate_password_hash('your_strong_password'))

Third, add rate limiting to prevent brute-force attacks. You can use Flask-Limiter to restrict the number of authentication attempts per IP or user:

from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

limiter = Limiter(key_func=get_remote_address, default_limits=["5 per minute"])
app = Flask(__name__)
limiter.init_app(app)

@app.route('/admin')
@limiter.limit("5 per minute")
def admin_page():
    auth = request.authorization
    if not auth or not check_auth(auth.username, auth.password):
        return authenticate()
    return 'Admin Panel: Top secret data'

For production deployments, consider using an external authentication provider or API gateway to manage credentials and TLS termination. middleBrick’s scans can validate that HTTPS is enforced and that authentication endpoints include proper rate limiting and secure credential handling. With the Pro plan, you can enable continuous monitoring so that any regression in authentication controls is flagged promptly, and the GitHub Action can fail builds if a new route exposes Basic Auth without HTTPS.

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

Does using Basic Auth over HTTPS fully protect against Broken Authentication?
Using Basic Auth over HTTPS protects credentials in transit, but it does not address risks such as weak passwords, lack of rate limiting, hardcoded credentials, or missing account lockout policies. Additional controls like secure credential storage, rate limiting, and multi-factor authentication are still required.
How does middleBrick detect Broken Authentication in Flask apps using Basic Auth?
middleBrick tests the unauthenticated attack surface and checks for endpoints that expose authentication mechanisms without HTTPS, lack rate limiting, or rely on weak credential checks. Findings include guidance on enforcing transport security and secure credential management.