Security Tip: Is `strip_tags()` Secure?
[Tip#63] PHP includes a some really handy security-focused functions, but you need to know how to use them correctly, or you risk leaving a significant vulnerability waiting to be exploited! 😱
It’s common to find older PHP apps use some of the built-in security functions, such as strip_tags()
, htmlspecialchars()
, and htmlentities()
. They each work in different ways and but are they actually secure enough to use? And when should you use each of them?
Let’s take a look at strip_tags()
and hopefully answer those question!
According to the PHP docs:
This function tries to return a string with all NULL bytes, HTML and PHP tags stripped from a given string. It uses the same tag stripping state machine as the fgetss()
function.
The function itself has two parameters, the first is required and is the string value being stripped, and the second is an optional list of allowed HTML tags.
strip_tags(string $string, array|string|null $allowed_tags = null): string
But is it secure?
Let’s answer that question through a couple of examples…
return strip_tags("Hello <b>World</b>!")
// Hello World!
✅ So far so good, it does what it says it does - strip HTML tags out of strings!
return strip_tags("Hello <img src=x onerror=\"alert('Boom!')\"> World!");
// Hello World!
✅ As we’d expect, it strips out complex tags too.
$string = "Hello <img src=x onerror=\"alert('Boom!')\"> World!";
return strip_tags($string, "<img>");
// Hello <img src=x onerror="alert('Boom!')"> World!
❌ Unfortunately, it blindly allows the entire tag, which includes any XSS payloads. You cannot use strip_tags()
with user input when you want to allow some tags. Instead, what you need is a fully featured HTML Purifier.
$value = strip_tags("' onload=\"alert('Boom!')\" '");
return "<input type='text' name='comments' value='{$value}'>";
// <input type='text' name='comments' value='' onload="alert('Boom!')" ''>
❌ As we should expect, it’s not context aware so although it will remove tags, it won’t escape anything else. This means you cannot use it inside tag attributes safely.
Summary
strip_tags()
is safe to use when you’re removing entirely HTML tags from content going straight on the page outside any attributes or complex HTML strictures.
Don’t use it if you need to allow specific tags (use a Purifier instead), and don’t use it inside attributes or complex structures.