Is filter_var a good way to go?

Viewed 22026

Is filter_var any good for filtering data? What kind of bad data will it filter? I do use mysql_real_escape_string but I wonder if adding filter_var will help?

5 Answers

To defend from SQL injection use prepared statements if possible. If not, use mysql_real_escape_string for strings, (int) casting or intval() for integers, (float) or floatval() for floats and addcslashes($input, '%_') for strings to be used inside LIKE statements. Things get even more complicated when trying to escape strings to be used inside RLIKE statements.

For filtering HTML content, the best would be strip_tags (without passing $allowable_tags), but... you may not like/want it, in which case the most affordable solution is:

$escaped = htmlspecialchars($input, ENT_QUOTES, $your_charset);

A more reliable solution would be to use a library like HTML Purifier

Filter functions are OK, but some of them are more validators than filters. Depending on your needs you may find some of them useful.

You adjust filter_var by using it with the FILTER_* constants. It sounds like you're looking for sanitisation of data (actually adjusting the data to make it safe*) rather than validation (checking the data is safe).

Different filters can help with different tasks. While mysql_real_escape_string is ok for sanitising data to prevent SQL injection it's no good for outputting data that may contain HTML. Here's a couple of filter's I'd use for everyday tasks:

  • FILTER_SANITIZE_SPECIAL_CHARS - useful for displaying (not removing) HTML code, preventing XSS attacks and converting symbols to HTML entities.
  • FILTER_SANITIZE_STRING with the STRIP_LOW/HIGH flags - actually removes HTML (see strip_tags).
  • FILTER_SANITIZE_URL - makes URLs safe*.
  • FILTER_SANITIZE_EMAIL - makes email addresses safe, although I'd prefer to use it's validation cousin before storing the address.

* I use safe loosely, I'm of the opinion that you can never be too sure.

It really depends what you're trying to do, I can't really answer without knowing specifics. The possible filters and their effects are listed here: Types of filters

Just based on some minor testing, I've come to the conclusion that filter_var's constants are not trustworthy.

For example:

filter_var('a@b-.c', FILTER_VALIDATE_EMAIL); // valid
filter_var('http://.', FILTER_VALIDATE_URL); // valid
filter_var('a@b-.c', FILTER_SANITIZE_EMAIL); // a@b-.c
filter_var('http://.', FILTER_SANITIZE_URL); // http://.

These are clearly invalid values, but pass filter_var's constants. Do not trust filter_var.

Related