Redirect After Post
ID |
php.redirect_after_post |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Reliability |
Language |
Php |
Tags |
reliability, web |
Description
Reports a request handler that reads the $_POST superglobal and then renders a page directly
with echo or print instead of issuing an HTTP redirect. This breaks the Post/Redirect/Get
(PRG) pattern: refreshing the resulting page or using the browser back button re-submits the form,
replaying the POST and its side effects (a duplicate order, a double charge).
Rationale
After processing a POST, a handler should respond with a Location redirect so the browser
performs a fresh GET of a result page. A refresh then re-requests that GET page harmlessly. When
the handler instead echoes the result inline, the page in the browser’s history is the POST
response, so a refresh re-posts the form.
The check is a deliberately conservative structural heuristic — PHP is too dynamic for precise
flow analysis. It flags the first $_POST read inside a function that also produces direct output
(echo/print) yet issues no header('Location: …') call. Handlers that return data without
direct output, or that redirect, are not reported; cross-function dispatch is outside its reach.
<?php
function badHandler()
{
$name = $_POST['name']; // FLAW — echoes the result with no redirect
echo "Saved $name";
}
function goodHandler()
{
$name = $_POST['name']; // OK — redirects after handling the POST
header('Location: /done');
exit;
}
Remediation
After handling the POST, send a redirect to a result page with header('Location: …') followed
by exit;, and render the result on the subsequent GET request rather than inline.