mikelbring
mikelbring

Reputation: 1492

Is filter_var a good way to go?

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?

Upvotes: 42

Views: 23111

Answers (5)

John Thomas
John Thomas

Reputation: 21

It all depends on what you mean by a valid url or a valid email.

For example [email protected] - well, you could filter top level domains to exclude .c but the list of top level domains is not constant. Moreover all the characters are valid. Even though this looks weird and is almost certainly not valid, many regex filters will validate it too.

With the email [email protected] or url http://. if displayed or used in links they will do no harm, even if they go nowhere.

I think part of the issue is the question of how loose do you want your filters. If the big concern is XSS or SQL injection or otherwise preventing dangerous input, whether or not the value is usable may be irrelevant, so this sort of filter may do the trick.

If you want to make sure the value is not just safe but also usable, that's a trickier beast.

Upvotes: 2

Ross
Ross

Reputation: 46987

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.

Upvotes: 19

eyelidlessness
eyelidlessness

Reputation: 63519

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

For example:

filter_var('[email protected]', FILTER_VALIDATE_EMAIL); // valid
filter_var('http://.', FILTER_VALIDATE_URL); // valid
filter_var('[email protected]', FILTER_SANITIZE_EMAIL); // [email protected]
filter_var('http://.', FILTER_SANITIZE_URL); // http://.

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

Upvotes: -5

Ionuț G. Stan
Ionuț G. Stan

Reputation: 179098

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.

Upvotes: 25

Chad Birch
Chad Birch

Reputation: 74518

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

Upvotes: 1

Related Questions