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')