Sanitizing

Sanitizing Filters and What Not to Rely On

A FILTER_SANITIZE_* filter never fails. It deletes or encodes characters and hands back a string, so bad input turns silently into different input:

What the sanitizing filters do to input (sanitize.php)PHP
<?php
echo implode("\n", [
    filter_var('12abc3', FILTER_SANITIZE_NUMBER_INT),
    filter_var('2.5e3', FILTER_SANITIZE_NUMBER_FLOAT),
    filter_var('ann (at) x.io', FILTER_SANITIZE_EMAIL),
    filter_var('<b>Hi</b> & co', FILTER_SANITIZE_SPECIAL_CHARS),
    filter_var("Hi\x07\x00 there", FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW),
]), "\n";
Output
123
253
annatx.io
&#60;b&#62;Hi&#60;/b&#62; &#38; co
Hi there

"12abc3" became 123, 2.5e3 became 253 (the dot and e need FILTER_FLAG_ALLOW_FRACTION and FILTER_FLAG_ALLOW_SCIENTIFIC), and "(at)" became annatx.io: validate and reject instead. Encoding HTML on the way in double-escapes on output and corrupts JSON or CSV; escape at output (HTML-Safe Output and Escaping). Keep FILTER_UNSAFE_RAW (alias FILTER_DEFAULT) with FILTER_FLAG_STRIP_LOW, which removed the bell and NUL. FILTER_SANITIZE_STRING is deprecated since 8.1 ("use htmlspecialchars() instead"), and FILTER_SANITIZE_ADD_SLASHES is no defense against SQL injection (Databases with PDO).