extract() Security Risk
debt(d3/e3/b3/t5)
Closest to 'default linter catches the common case' (d3). The term's detection_hints list phpcs, semgrep, and phpstan as tools that can flag extract($_POST/GET) patterns. These are standard PHP static analysis tools that catch the common dangerous usage with automated detection marked as 'yes'. Not d1 because PHP itself doesn't prevent extract() at compile time.
Closest to 'simple parameterised fix' (e3). The quick_fix states to replace extract() with explicit variable assignment or filter_input() — this is a straightforward pattern replacement within the affected file(s). Not e1 because you need to identify which variables were being extracted and assign them explicitly, which takes more than a single-line change but remains localized.
Closest to 'localised tax' (b3). extract() usage is typically confined to specific files (form handlers, template files). The applies_to shows it affects web/cli contexts, but the actual burden is limited to wherever extract() was called. It doesn't create system-wide dependencies or architectural constraints — just localized technical debt that can be fixed file by file.
Closest to 'notable trap' (t5). The misconception explicitly states that developers believe EXTR_PREFIX_SAME is safe for user input, when attackers can still target predictable prefixed names. The common_mistakes show developers don't realize extract() overwrites existing variables by default (EXTR_OVERWRITE). This is a documented gotcha that experienced PHP devs learn, but it contradicts the convenient appearance of the function.
TL;DR
Explanation
extract(array $array) creates one variable per key in the current scope. extract($_POST) is as dangerous as register_globals — attackers can set any variable: ?role=admin overwrites $role. Even with EXTR_PREFIX_ALL, if the prefix is known it can be targeted. Extract should only be used with trusted, bounded arrays (configuration, template variables) and never with user input. PHP_CodeSniffer and PHPStan flag extract() usage. Rector can suggest replacements. Use explicit variable assignment or list()/array destructuring instead.
Common Misconception
Why It Matters
Common Mistakes
- Calling extract($_POST) or extract($_GET) for convenience.
- Using extract() in template files where variables could be overwritten.
- Not knowing extract() overwrites existing variables by default (EXTR_OVERWRITE).
Code Examples
// extract() on user input — catastrophic
extract($_POST); // ?role=admin&authenticated=1
if ($authenticated && $role === 'admin') {
// Attacker gains admin access
}
// Explicit extraction — only what you need:
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_SPECIAL_CHARS);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
// If you must use extract, use trusted bounded data:
$templateVars = ['title' => 'Home', 'year' => date('Y')];
extract($templateVars, EXTR_SKIP); // Never user input