To protect against common attacks sanitization functions are often used to impose restrictions on the input. These can be very effective at stopping our payloads from functioning. However, it is essential to understand what they are doing, as they do not provide blanket protection against all attacks, and can easily provide a false sense of security or make a vulnerability more difficult to spot. The table below highlights which interesting characters can survive each sanitization function.

Function<>'"Comments
esc_attr&lt;&gt;&#039;&quot;Difficult to beat, see More Tricks below
esc_html&lt;&gt;&#039;&quot;Difficult to beat, see More Tricks below
esc_js&lt;&gt;\'&quot;Difficult to beat, see More Tricks below
esc_sql<>\'\"XSS, potential for second order SQL injection
esc_url&#039;Difficult to beat, see More Tricks below
esc_url_raw'SQLi or low chance of XSS via attribute injection
filter_var<>'"No sanitization by default. SQLi or XSS
filter_input<>'"No sanitization by default. SQLi or XSS
sanitize_text_field'"SQLi or XSS via attribute injection
sanitize_email'SQLi or low chance of XSS via attribute injection
sanitize_file_nameUnlikely to bypass
sanitize_keyUnlikely to bypass
sanitize_url'SQLi or XSS via attribute injection
sanitize_user'"SQLi or XSS via attribute injection
sanitize_title-Unlikely to bypass
strip_tags'"SQLi or XSS via attribute injection
wp_strip_all_tags'"SQLi or XSS via attribute injection
htmlentities&lt;&gt;'&quot;SQLi or low chance of XSS via attribute injection
htmlspecialchars&lt;&gt;'&quot;SQLi or low chance of XSS via attribute injection
Key:Pass ThruHTML EncodedModifiedRemoved

Note that most of the WordPress esc_ functions have similar variants that do the same thing but with support for translations. They have the same name but are followed by __, _e or _x (e.g. esc_attr__, esc_attr_e and esc_attr_x)

More Tricks

Often encountering a sanitization function on an attacker-controlled variable will result in game-over. However, there are still a few things we can look for as attacker that may allow us to get past the intended protection. Let’s take a look at some of them:

Context Mistakes

Some of these sanitization functions rely on developers using them in the exact right context. Sometimes this can be tricky and prone to errors. For example, esc_attr works great to remove XSS via attribute injection when use in HTML, however it only works if the attribute is enclosed in quotes. For example the following code is still subtly vulnerable:

// Not using quotes around an escaped attribute, allows us to use spaces to inject additional atttributes.
echo "<input type=text value=" . esc_attr($_GET['username']) . ">";

Similarly, we can find that using the wrong sanitization function for the context can result in a vulnerability:

// Using the wrong escaping method. Here esc_js uses slashes to escape quotes, and HTML ignores slashes before quotes, so we can get XSS.
echo '<input type=text value="' . esc_js($_GET['username']) . '">';