Missing Tls in Flask with Bearer Tokens
Missing Tls in Flask with Bearer Tokens — how this specific combination creates or exposes the vulnerability
Transport Layer Security (TLS) is the baseline mechanism that protects confidentiality and integrity in transit. When a Flask API that uses bearer tokens deliberately runs without enforcing TLS (HTTPS), the tokens are exposed as they traverse the network. middleBrick flags Missing TLS as a finding because unencrypted channels allow multiple realistic attack vectors, including on-path sniffing and credential replay.
In practice, an unencrypted HTTP endpoint that accepts an Authorization: Bearer
Moreover, the combination of missing TLS and bearer tokens can amplify other issues discovered by middleBrick, such as BOLA/IDOR and Data Exposure. An intercepted token can be reused to impersonate a user or service, and without TLS, additional security mechanisms like signed JWT claims provide limited protection in transit. Attack patterns like Man-in-the-Middle (MitM) and session hijacking map directly to OWASP API Top 10:2023 A02 — Broken Authentication, when transport protections are absent.
middleBrick validates this by testing the unauthenticated attack surface and cross-referencing OpenAPI/Swagger definitions with runtime checks. If the spec describes security requirements like "schemes: [https]" or "securitySchemes" using bearer formats but the live endpoint serves responses over plain HTTP, the discrepancy is surfaced as a high-severity finding. The scanner does not assume internal protections such as downstream load balancers or proxies; it reports what it observes at the endpoint under test.
Remediation guidance centers on enforcing TLS and validating that tokens are only accepted over secure channels. Developers should configure Flask to redirect HTTP to HTTPS or terminate TLS at the ingress point, ensuring that all traffic to bearer-token-protected routes is encrypted. Certificate management and strong cipher suites remain the responsibility of the platform operator, but the scanner highlights the absence of transport-layer encryption as a concrete, actionable risk.
Bearer Tokens-Specific Remediation in Flask — concrete code fixes
Securing bearer tokens in Flask requires both application-level enforcement of HTTPS and disciplined handling of the Authorization header. Below are concrete, working examples that demonstrate how to implement these controls correctly.
First, ensure your Flask application rejects or redirects plain HTTP requests. A common pattern is to use a before_request hook that checks the request scheme and aborts if TLS is not in use:
from flask import Flask, request, abort
app = Flask(__name__)
@app.before_request
def enforce_https():
if not request.is_secure:
abort(403, description="HTTPS is required")
@app.route("/api/resource")
def protected_resource():
auth = request.headers.get("Authorization")
if not auth or not auth.startswith("Bearer "):
abort(401, description="Missing or invalid Authorization header")
token = auth.split(" ", 1)[1]
# Perform token validation and scope checks here
return {"status": "ok"}, 200
if __name__ == "__main__":
app.run(ssl_context=("cert.pem", "key.pem"))
This example enforces HTTPS before any route logic executes. The ssl_context parameter should point to valid certificate and key files managed outside the application, such as through a reverse proxy or container orchestration platform. Note that request.is_secure reflects the forwarded proto only if you correctly configure proxies; in production, prefer infrastructure-level TLS termination with strict transport rules.
Second, validate bearer tokens rigorously and avoid logging sensitive values. A safer approach separates extraction from validation and ensures tokens are not exposed in logs or error messages:
import re
from flask import Flask, request, jsonify
app = Flask(__name__)
BEARER_PATTERN = re.compile(r"^Bearer\s+(\S+)$")
def extract_token(req):
header = req.headers.get("Authorization", "")
match = BEARER_PATTERN.match(header)
return match.group(1) if match else None
@app.route("/api/read")
def read_resource():
token = extract_token(request)
if token is None:
return jsonify({"error": "invalid_token"}), 401
# Verify token signature, issuer, scopes, and expiration
if not verify_token(token):
return jsonify({"error": "invalid_token"}), 401
return jsonify({"data": "protected"}), 200
def verify_token(token):
# Placeholder: integrate with your auth provider or JWKS validation
return token == "expected-secure-token"
if __name__ == "__main__":
app.run(ssl_context=("cert.pem", "key.pem"))
This second example demonstrates a structured extraction function and a placeholder for robust token validation. In real deployments, replace verify_token with checks against an identity provider, JWKS endpoint, or validated introspection response. The pattern avoids including the full Authorization header in logs and keeps token handling explicit.
Finally, complement code changes with infrastructure and operational practices: use HTTP-to-HTTPS redirects at the load balancer or reverse proxy, adopt HSTS where appropriate, rotate bearer tokens regularly, and monitor for unauthorized usage. middleBrick’s scans can be run repeatedly to confirm that the endpoint now serves responses only over TLS and that the security findings reflect the updated configuration.
Related CWEs: encryption
| CWE ID | Name | Severity |
|---|---|---|
| CWE-319 | Cleartext Transmission of Sensitive Information | HIGH |
| CWE-295 | Improper Certificate Validation | HIGH |
| CWE-326 | Inadequate Encryption Strength | HIGH |
| CWE-327 | Use of a Broken or Risky Cryptographic Algorithm | HIGH |
| CWE-328 | Use of Weak Hash | HIGH |
| CWE-330 | Use of Insufficiently Random Values | HIGH |
| CWE-338 | Use of Cryptographically Weak PRNG | MEDIUM |
| CWE-693 | Protection Mechanism Failure | MEDIUM |
| CWE-757 | Selection of Less-Secure Algorithm During Negotiation | HIGH |
| CWE-261 | Weak Encoding for Password | HIGH |