Execution After Redirect ('EAR')
ID |
python.execution_after_redirect |
Severity |
low |
Resource |
Other |
Language |
Python |
Tags |
CWE:698, NIST.SP.800-53 |
Description
Detects code that continues to execute after issuing an HTTP redirect, potentially leading to unintended information disclosure or behavior.
Rationale
Execution-after-redirect vulnerabilities occur when a web application continues processing code after issuing a redirect (e.g., via redirect()
or setting HTTP status 302). In Python web frameworks like Flask or Django, this can cause sensitive logic to run unintentionally, resulting in issues like information leakage, authorization bypass, or unintended side effects.
Consider the following Flask example:
from flask import Flask, redirect, request
app = Flask(__name__)
@app.route('/logout')
def logout():
session.pop('user_id', None)
return redirect('/login')
do_cleanup() # This will still execute!
Here, do_cleanup()
is executed even after the redirect is issued, which can lead to undefined behavior or security problems.
Another example showing the vulnerability more clearly:
from flask import Flask, redirect
app = Flask(__name__)
@app.route('/transfer')
def transfer():
if not user_is_authenticated():
return redirect('/login')
perform_transfer() # This still runs even if the user is unauthenticated!
The call to perform_transfer()
should not execute after the redirect()
, but in this structure, it will unless explicitly returned early.
Remediation
To prevent execution after redirection in Python applications, ensure that no additional code executes after a redirection call. Always use return
statements directly with redirect functions or after setting redirect responses to terminate execution flow clearly.
Correct usage:
from flask import Flask, redirect, session
app = Flask(__name__)
@app.route('/logout')
def logout():
session.pop('user_id', None)
return redirect('/login') # Execution stops here
For more complex logic:
@app.route('/transfer')
def transfer():
if not user_is_authenticated():
return redirect('/login') # Prevents perform_transfer() from running
return perform_transfer() # Safe to call now
Best Practices:
-
Always pair
redirect()
with areturn
keyword. -
Avoid side-effect-prone logic after redirection unless absolutely required and well-audited.
-
Document all intentional post-redirect logic to make exceptions explicit and justifiable.