Password In Redirect

ID

python.password_in_redirect

Severity

critical

Resource

Information Leak

Language

Python

Tags

CWE:359, NIST.SP.800-53, OWASP:2021:A7, PCI-DSS:6.5.3

Description

Sensitive information such as passwords should not be included in URLs, especially as part of redirects, as this may lead to information exposure through logs, browser history, or referer headers.

Rationale

The password_in_redirect rule flags situations where sensitive information, particularly passwords, is included in a URL used in a redirect operation. This is a security concern because URLs may be logged in various locations (e.g., web server logs, proxy logs, browser history), making the sensitive information potentially accessible to unauthorized users.

In Python web applications, this vulnerability is commonly found when developers manually construct URLs with sensitive data in query parameters for redirect operations using libraries like Flask or Django.

# Vulnerable Flask example
from flask import Flask, redirect, request

app = Flask(__name__)

@app.route('/login', methods=['POST'])
def login():
    password = request.form['password']
    return redirect(f'/home?password={password}')  # Password in URL
# Vulnerable Django example
from django.shortcuts import redirect

def login_view(request):
    password = request.POST.get('password')
    return redirect(f'/dashboard?password={password}')  # Sensitive data in redirect

Including the password in the URL not only exposes it to logs but also might allow it to be leaked through the HTTP Referer header when navigating to external domains.

Remediation

To remediate this issue, sensitive information like passwords should never be included in URLs or query parameters, especially in redirects. Instead, rely on secure server-side session management to persist state or context across requests.

Use secure methods for authentication and avoid exposing secrets in transport layers not designed for confidentiality.

# Secure Flask example using session
from flask import Flask, redirect, request, session, url_for

app = Flask(__name__)
app.secret_key = 'your_secret_key'

@app.route('/login', methods=['POST'])
def login():
    password = request.form['password']
    # Authenticate user here
    session['authenticated'] = True
    return redirect(url_for('home'))  # No sensitive data in URL
# Secure Django example using session
from django.shortcuts import redirect
from django.contrib.auth import authenticate, login

def login_view(request):
  if request.method == 'POST':
    user = authenticate(request, username=request.POST['username'], password=request.POST['password'])
    if user is not None:
      login(request, user)
      return redirect('/dashboard')

Configuration

The detector has the following configurable parameters:

  • passwordPattern, that indicates the regex used to determine if the redirect contains a password.