strip_tags()
debt(d5/e3/b3/t9)
Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep and phpstan — both specialist SAST/static-analysis tools — as the means to catch the pattern of strip_tags() used as sole XSS protection or with allowed tags lacking attribute sanitisation. Default linters would not flag this, and it is silent at runtime until an attacker exploits it.
Closest to 'simple parameterised fix' (e3). The quick_fix indicates replacing strip_tags() with htmlspecialchars() for HTML output, or combining both for plain-text output. This is a targeted find-and-replace of the sanitisation call at each output point, touching potentially a few files but not a cross-cutting architectural change.
Closest to 'localised tax' (b3). The misuse is typically concentrated in output/view layers or specific input-handling routines. It applies to web and cli contexts but does not define the system's shape; fixing it is scoped to the places where user content is echoed, not a codebase-wide structural commitment.
Closest to 'catastrophic trap — the obvious way is always wrong' (t9). The misconception field states it directly: developers believe strip_tags() prevents XSS, but event-handler attributes on allowed tags still execute JavaScript. The function's name and common usage strongly imply safety, yet the 'obvious' usage pattern (stripping tags to sanitise output) is always wrong as a standalone XSS defence — exactly matching the t9 anchor.
Also Known As
TL;DR
Explanation
strip_tags($string) removes all HTML and PHP tags from a string. It is often misused as an XSS prevention mechanism, but it is not reliable for this purpose — it can be bypassed with malformed tags, and it strips tags rather than encoding them, destroying legitimate content. The correct defence against XSS in HTML output is htmlspecialchars(). Use strip_tags() only when you genuinely want to remove markup — such as sanitising input for plain-text storage — and never as a substitute for output encoding.
Common Misconception
Why It Matters
Common Mistakes
- Using strip_tags() as an XSS defence — event attributes in allowed tags still execute JavaScript.
- Passing an allowlist of tags without sanitising the attributes on those allowed tags.
- Not using htmlspecialchars() after strip_tags() — the output still needs context-appropriate escaping.
- Using strip_tags() to clean user input for database storage — the issue is output encoding, not stripping.
Avoid When
- Never rely on strip_tags() as your sole XSS prevention strategy — encoded payloads, SVG, and CSS survive tag stripping.
- Do not use strip_tags() to sanitise input for HTML output — use htmlspecialchars() or an HTML purifier library instead.
When To Use
- Use strip_tags() only when you need to remove HTML tags from content for plain-text display — not as an XSS defence.
- Combine strip_tags() with htmlspecialchars() when displaying user content in a plain-text context.
Code Examples
// strip_tags() as XSS defence — easily bypassed
$input = strip_tags($_POST['bio']);
echo $input; // <scr<script>ipt>alert(1)</scr</script>ipt> survives
// strip_tags() — useful for producing plain text, not for XSS prevention
$plain = strip_tags($htmlContent); // strip for plain-text email
$wordCount = str_word_count(strip_tags($body)); // word count
// For PLAIN text output — use htmlspecialchars():
echo htmlspecialchars($userInput, ENT_QUOTES|ENT_SUBSTITUTE, 'UTF-8');
// For RICH text output — use HTMLPurifier:
$purifier = new HTMLPurifier(HTMLPurifier_Config::createDefault());
$clean = $purifier->purify($_POST['description']);
echo $clean;