HIGH crlf injectionflaskbearer tokens

Crlf Injection in Flask with Bearer Tokens

Crlf Injection in Flask with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Crlf Injection occurs when user-controlled data is reflected into HTTP headers without sanitization, allowing an attacker to inject newline characters (\r\n) that break header structure. In Flask, APIs commonly use Bearer Tokens passed via the Authorization header (e.g., Authorization: Bearer ). When developers log, echo, or misuse incoming headers—such as copying a token value into another response header or using it to build Location or Set-Cookie values—the application can inadvertently reflect attacker-controlled sequences.

For example, if an endpoint accepts a custom header like X-API-Key and directly includes its value in a downstream Location header for redirects, an attacker can supply a token containing \r\nSet-Cookie: injected=value. Because CRLF characters split headers, the injected line becomes a separate header, enabling session fixation, cache poisoning, or client-side redirection to malicious sites. MiddleBrick’s scan tests this vector by submitting payloads such as %0d%0aSet-Cookie: malicious=1 in header values and checking whether the response contains the injected header lines. The tool also cross-references OpenAPI/Swagger specs (2.0, 3.0, 3.1) with runtime findings to highlight mismatches between declared security schemes and actual behavior, such as Bearer-only definitions that do not account for header injection paths.

Even when Bearer tokens are validated, frameworks like Flask may expose token material through verbose error messages or logs if developers concatenate Authorization header values into insecure redirects or responses. An attacker does not need authentication to probe these paths because middleBrick scans the unauthenticated attack surface. This makes Crlf Injection in Flask with Bearer Tokens particularly dangerous: tokens may be treated as opaque strings, but their reflection in headers can compromise integrity and enable follow-on attacks like cookie injection or open redirects.

Bearer Tokens-Specific Remediation in Flask — concrete code fixes

Remediation centers on strict input validation, avoiding header reflection, and using framework-safe constructs. Never directly embed user-supplied values into headers. If you must forward or log tokens, treat them as opaque strings and ensure they are not parsed or re-emitted as header lines. Below are concrete Flask patterns that mitigate Crlf Injection when Bearer Tokens are involved.

1. Reject tokens containing newline or carriage-return characters at the edge

from flask import Flask, request, abort
import re

app = Flask(__name__)

CRLF_RE = re.compile(r'[\r\n]')

def is_safe_token(token: str) -> bool:
    return CRLF_RE.search(token) is None

@app.before_request
def validate_auth_header():
    auth = request.headers.get('Authorization', '')
    if auth.startswith('Bearer '):
        token = auth[7:].strip()
        if not token or not is_safe_token(token):
            abort(400, 'Invalid token')

2. Use secure redirects with predefined URLs, never concatenate Location from user input

from flask import Flask, request, redirect, url_for

app = Flask(__name__)

@app.route('/gateway')
def gateway():
    # BAD: redirect(request.args['next'])  # user-controlled
    # Instead, map a short alias to a trusted destination
    target = request.args.get('target')
    allowed = {'dashboard': '/app', 'settings': '/app/settings'}
    url = allowed.get(target)
    if not url:
        abort(400, 'Invalid target')
    return redirect(url)

3. Avoid echoing Authorization headers in responses or logs in unsafe ways

import logging
logger = logging.getLogger('api')

@app.route('/data')
def get_data():
    auth = request.headers.get('Authorization', '')
    # Log only that auth was present, not the full header value
    logger.info('Authenticated request', extra={'auth_present': bool(auth)})
    # Process token safely without reflection
    return {'status': 'ok'}

4. Enforce strict Content-Security-Policy and avoid Set-Cookie from untrusted input

@app.after_request
def add_security_headers(response):
    response.headers['Content-Security-Policy'] = "default-src 'self'"
    # Ensure no injected Set-Cookie from app logic
    if 'Set-Cookie' in response.headers:
        # In practice, validate or drop any Set-Cookie that you did not explicitly set
        pass
    return response

5. Use WSGI middleware to sanitize headers early

class CrlfSanitizer:
    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        # Remove dangerous newlines from header-like custom headers
        headers = environ.get('HTTP_X_CUSTOM_HEADERS', '')
        if '\r' in headers or '\n' in headers:
            start_response('400 Bad Request', [('Content-Type', 'text/plain')])
            return [b'Invalid characters in headers']
        return self.app(environ, start_response)

app.wsgi_app = CrlfSanitizer(app.wsgi_app)

These patterns ensure Bearer Tokens are validated and never reflected verbatim into headers where CRLF characters can split responses. Combine these checks with automated scanning—middleBrick’s CLI can be run locally with middlebrick scan <url> to verify that your endpoints reject or safely handle maliciously crafted tokens.

Frequently Asked Questions

Can Crlf Injection be exploited even when the API uses Bearer token authentication?
Yes. Authentication confirms identity but does not prevent injection if the application reflects token values into other headers or uses them to build Location/Set-Cookie values. Attackers can inject newline sequences into token-like strings and manipulate header boundaries.
Does scanning with middleBrick require authentication to detect Crlf Injection in Flask APIs?
No. middleBrick scans the unauthenticated attack surface by default. It submits payloads such as %0d%0aSet-Cookie: injected=1 in header fields to observe whether the response contains injected lines, without needing credentials.