HIGH phishing api keysflaskbearer tokens

Phishing Api Keys in Flask with Bearer Tokens

Phishing API Keys in Flask with Bearer Tokens

A common pattern in Flask APIs is to accept a Bearer token in the Authorization header for authentication. Attackers can exploit developer habits to phish these credentials. For example, an attacker might send a convincing email or message that directs a user to a malicious site. That site can then use JavaScript to make cross-origin requests to your Flask endpoint, attempting to trick the user’s browser into sending the Authorization header with a valid token. Because the Authorization header is included in cross-origin requests when credentials are allowed, the attacker’s backend can capture the token. This is a phishing technique that targets the token itself rather than the application’s login page.

Consider a Flask route that expects a Bearer token in the header:

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/api/data")
def get_data():
    auth = request.headers.get("Authorization", "")
    if auth.startswith("Bearer "):
        token = auth.split(" ", 1)[1]
        # Use token to access a downstream service
        return jsonify({ "status": "ok", "token": token })
    return jsonify({ "error": "Unauthorized" }), 401

If a user is tricked into visiting a malicious site while authenticated, the attacker’s script can initiate a request to /api/data with the user’s credentials. The browser will include the Authorization header automatically if the request is made with credentials and the endpoint does not enforce strict CORS policies. The attacker can then log the token and use it to impersonate the user against downstream services. This risk is elevated when tokens are long-lived or when the API does not validate the Origin header or use anti-CSRF protections for state-changing operations.

Another phishing scenario involves attackers hosting a lookalike dashboard that claims to be your API documentation or admin panel. Users are lured into entering their Authorization header values, which are then harvested. Because middleBrick scans unauthenticated attack surfaces, such exposed endpoints that accept and reflect tokens can be detected through pattern analysis and runtime testing. The scanner checks for missing security headers, overly permissive CORS, and endpoints that echo credentials, which helps identify weaknesses that facilitate phishing.

Bearer Tokens-Specific Remediation in Flask

Remediation focuses on never exposing tokens in browser-executable code, enforcing strict CORS, and avoiding the reflection of raw Authorization headers. Do not return the token in API responses, even in debug mode. Instead, treat the token as an opaque reference to your backend and use server-side sessions or short-lived access tokens with refresh token rotation.

Implement strict CORS and do not allow credentials on public origins:

from flask import Flask, request, jsonify
from flask_cors import CORS, cross_origin

app = Flask(__name__)
# Restrict CORS to known frontends; do not allow "*" with credentials
CORS(app, resources={r"/api/*": {"origins": ["https://trusted.example.com"], "supports_credentials": True}})

@app.route("/api/data")
def get_data():
    auth = request.headers.get("Authorization", "")
    if auth.startswith("Bearer "):
        token = auth.split(" ", 1)[1]
        # Validate token with your auth provider, do not echo it back
        if is_valid_token(token):
            return jsonify({ "status": "ok", "data": fetch_protected_data(token) })
    return jsonify({ "error": "Unauthorized" }), 401

def is_valid_token(token: str) -> bool:
    # Verify token with your identity provider, check revocation, scopes, and expiration
    return True

def fetch_protected_data(token: str):
    # Call downstream services using the token, but do not return it to the client
    return { "protected": "data" }

Use secure, HttpOnly cookies for session tokens when possible, and if you must use the Authorization header, ensure that your frontend never reads it. Configure your API to reject tokens in URLs or query parameters, as these are more likely to be leaked in logs or referrers. Apply rate limiting to mitigate credential stuffing attempts that try to guess or phish valid tokens. With the Pro plan, continuous monitoring can detect endpoints that echo tokens and alert you before credentials are phished at scale.

Finally, validate and sanitize all inputs, enforce HTTPS with HSTS, and rotate compromised tokens immediately. The GitHub Action can enforce a minimum security score before merges, and the MCP Server allows you to scan APIs directly from your IDE to catch risky patterns early in development.

Frequently Asked Questions

Why should I avoid returning the token in API responses even during debugging?
Returning a token in responses can expose it to client-side JavaScript, browser extensions, or logs, enabling phishing and token theft. Treat tokens as sensitive server-side only.
How does CORS configuration help prevent token phishing in Flask APIs?
Strict CORS that limits origins and avoids wildcard credentials prevents malicious sites from making authenticated requests on behalf of users, reducing the risk that an attacker can capture tokens via cross-origin requests.