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.