Data security is important and often undervalued by designers, developers, and clients alike. Since PHP 5.2.0, data sanitization and validation has been made significantly easier with the introduction of data filtering. Today, we're going to take a closer look at these filters, how to use them, and build a few custom functions.
Tutorial Details
- Program: PHP
- Version: 5.2.0+
- Difficulty: Beginner
- Estimated Completion Time: 20 minutes
Introduction
I have always felt that it's easy to write code in PHP, and even easier to write bad code in PHP. The proliferation of PHP on the web has really been helped out by its use in popular open-source software packages like WordPress, Drupal, and Magento as well as major web applications like Facebook; with PHP being used in so many varied instances (dynamic websites, in-depth web applications, blogging platforms, content management systems, and e-commerce being only a subset of the many applications of PHP) the opportunities for dirty data and insecure systems are numerous. This tutorial will explain some methods of Getting Clean With PHP: Data Sanitization and Validation by focusing on several different forms of data inputs and how to use PHP filters and custom functions.

Why Sanitize and Validate?
In this tutorial, we are really focused on data inputs that users or external sources may provide. This means that we do not control the data we are receiving. All we can do is control what is done with it after we receive it. There are all sorts of threats related to data security from user-inputs and third-party data.
Some un-popular data security threats:
- Cross-Site Scripting (XSS): A form of code injection where a script is injected onto a website from a completely different website. This is by far the most common security vulnerability online. Two recent, very prominent examples of this technique are the Stalk Daily and Mikeyy Twitter Worms from earlier this year that used poorly sanitized inputs to launch Javascript via an "infected" Twitter web interface.
- SQL Injection: The second most common security vulnerability online, this is another form of code injection in which a script is used to participate in one of numerous exploitative behaviors including (but not limited to) exposing and/or gaining unauthorized access to data, altering data inside of a database, or simply injecting code to be rendered or executed within a website thereby breaking or altering the website.
- Cross-Site Request Forgery (CSRF/XSRF): A less common exploit that relies more on data sources like browser and session cookies than poorly sanitized and validated data inputs, CSRF (pronounced "sea-surf") can be used to execute commands on a website without the user's permission. One popular CSRF method is using an improperly formed image data URI or src value to execute a script instead of displaying an image.
- Improper Data: Not really a "security vulnerability" per se, improper data can cause hosts of problems for a website owner or database administrator. Often, improper data can break poorly coded websites or cause automated systems to crash. An example of this was the ability to alter entire MySpace profile pages by posting using all sorts of HTML/CSS hackery (Note: this may still work; I've not used MySpace in a long time).
For our purposes, we are going to only focus on server-side methods of improving data security with PHP, so let's see how the terms "sanitization" and "validation" are defined with relation to PHP. According to the PHP manual:
Validation is used to validate or check if the data meets certain qualifications. For example, passing in FILTER_VALIDATE_EMAIL will determine if the data is a valid email address, but will not change the data itself.
Sanitization will sanitize the data, so it may alter it by removing undesired characters. For example, passing in FILTER_SANITIZE_EMAIL will remove characters that are inappropriate for an email address to contain. That said, it does not validate the data.
Essentially, if your website is the nightclub that everybody wants to get into, validation checks the guest list and IDs at the door while sanitization acts as the bouncer that throws out any undesirables that happen to squeak past. With this in mind, let's take a look at PHP Filters Extension.
What Filters Do I Have?
All PHP installations are not created equal. While PHP 5.2.0 was the introduction of filters, not all installations have the same set of filters in their Filters Extension. Most installations will have all of the filters we're going to go over, but to teach you a bit about the Filters Extension, we're going to find out just what you have on your server. In the source download, I have included a file called getfilters.php that, once installed and run on your server, will display all of your filters (both data filters available through the filter_var function and stream filters available through stream_filter_append).
echo "<h1>Data Filters</h1>\n<table>\n<tr>\n";
echo "<td><strong>Filter ID</strong></td>\n";
echo "<td><strong>Filter Name</strong></td>\n</tr>";
foreach(filter_list() as $id =>$filter) {
echo "<tr><td>$filter</td><td>".filter_id($filter)."</td></tr>\n";
}
echo "</table>\n";
First, we get the array containing the list of all available filters with filter_list, then we loop through the array and echo out the filter name, find out the filter's assigned ID, and echo this ID as well.
How Do I Use A Filter?
PHP Filters for validation and sanitization are activated by passing at least two values to the PHP Filters Extension function filter_var. As an example, let's use the Sanitize Filter for an Integer number like so:
$value = '123abc456def'; echo filter_var($value, FILTER_SANITIZE_NUMBER_INT);
In the example, we have a variable $value that is passed through the Filters Extension function filter_var using the FILTER_SANITIZE_NUMBER_INT filter. This results in the following output:
123456
The Sanitize Filter for an Integer number removes all non-integer characters from the output and produces a clean integer. Within the download source code, you can try out various inputs and it will apply a number of common filters to your input value. I have included a number of different example strings that you can test out as well.
What Do The Different Filters Do?
The list below is not complete, but it does contain the majority of the filters that come standard with 5.2.0+ installations. Custom filters and those added from custom extensions are not included here.
FILTER_VALIDATE_BOOLEAN: Checks whether or not the data passed to the filter is a boolean value of TRUE or FALSE. If the value is a non-boolean value, it will return FALSE. The script below would echo "TRUE" for the example data $value01 but would echo "FALSE" for the example data $value02:
$value01 = TRUE;
if(filter_var($value01,FILTER_VALIDATE_BOOLEAN)) {
echo 'TRUE';
} else {
echo 'FALSE';
}
echo '<br /><br />'
$value02 = TRUE;
if(filter_var($value02,FILTER_VALIDATE_BOOLEAN)) {
echo 'TRUE';
} else {
echo 'FALSE';
}
FILTER_VALIDATE_EMAIL: Checks whether or not the data passed to the filter is a potentially valid e-mail address. It does not check whether the e-mail address actually exists, just that the format of the e-mail address is valid. The Script below would echo "TRUE" for the example data $value01 but would echo "FALSE" for the example data $value02 (because the second lacks the required @domain.tld portion of the e-mail address):
$value01 = 'test@example.com';
if(filter_var($value01,FILTER_VALIDATE_EMAIL)) {
echo 'TRUE';
} else {
echo 'FALSE';
}
echo '<br /><br />'
$value02 = 'nettuts';
if(filter_var($value02,FILTER_VALIDATE_EMAIL)) {
echo 'TRUE';
} else {
echo 'FALSE';
}
FILTER_VALIDATE_FLOAT: Checks whether or not the data passed to the filter is a valid float value. The Script below would echo "TRUE" for the example data $value01 but would echo "FALSE" for the example data $value02 (because comma separators are not allowed in float values):
$value01 = '1.234';
if(filter_var($value01,FILTER_VALIDATE_FLOAT)) {
echo 'TRUE';
} else {
echo 'FALSE';
}
echo '<br /><br />'
$value02 = '1,234';
if(filter_var($value02,FILTER_VALIDATE_FLOAT)) {
echo 'TRUE';
} else {
echo 'FALSE';
}
FILTER_VALIDATE_INT: Checks whether or not the data passed to the filter is a valid integer value. The Script below would echo "TRUE" for the example data $value01 but would echo "FALSE" for the example data $value02 (because fractions / decimal numbers are not integers):
$value01 = '123456';
if(filter_var($value01,FILTER_VALIDATE_INT)) {
echo 'TRUE';
} else {
echo 'FALSE';
}
echo '<br /><br />'
$value02 = '123.456';
if(filter_var($value02,FILTER_VALIDATE_INT)) {
echo 'TRUE';
} else {
echo 'FALSE';
}
FILTER_VALIDATE_IP: Checks whether or not the data passed to the filter is a potentially valid IP address. It does not check if the IP address would resolve, just that it fits the required data structure for IP addresses. The Script below would echo "TRUE" for the example data $value01 but would echo "FALSE" for the example data $value02:
$value01 = '192.168.0.1';
if(filter_var($value01,FILTER_VALIDATE_IP)) {
echo 'TRUE';
} else {
echo 'FALSE';
}
echo '<br /><br />'
$value02 = '1.2.3.4.5.6.7.8.9';
if(filter_var($value02,FILTER_VALIDATE_IP)) {
echo 'TRUE';
} else {
echo 'FALSE';
}
FILTER_VALIDATE_URL: Checks whether or not the data passed to the filter is a potentially valid URL. It does not check if the URL would resolve, just that it fits the required data structure for URLs. The Script below would echo "TRUE" for the example data $value01 but would echo "FALSE" for the example data $value02:
$value01 = 'http://net.tutsplus.com';
if(filter_var($value01,FILTER_VALIDATE_URL)) {
echo 'TRUE';
} else {
echo 'FALSE';
}
echo '<br /><br />'
$value02 = 'nettuts';
if(filter_var($value02,FILTER_VALIDATE_URL)) {
echo 'TRUE';
} else {
echo 'FALSE';
}
FILTER_SANITIZE_STRING: By default, this filter removes any data from a string that is invalid or not allowed in that string. For example, this will remove any HTML tags, like <script> or <strong> from an input string:
$value = '<script>alert('TROUBLE HERE');</script>';
echo filter_var($value, FILTER_SANITIZE_STRING);
This script would remove the tags and return the following:
alert('TROUBLE HERE');
FILTER_SANITIZE_ENCODED: Many programmers use PHP's urlencode() function to handle their URL Encoding. This filter essentially does the same thing. For example, this will encode any spaces and/or special characters from an input string:
$value = '<script>alert('TROUBLE HERE');</script>';
echo filter_var($value, FILTER_SANITIZE_ENCODED);
This script would encode the punctuation, spaces, and brackets, then return the following:
%3Cscript%3Ealert%28%27TROUBLE%20HERE%27%29%3B%3C%2Fscript%3E
FILTER_SANITIZE_SPECIAL_CHARS: This filter will, by default, HTML-encode special characters like quotes, ampersands, and brackets (in addition to characters with ASCII value less than 32). While the demo page does not make it abundantly clear without viewing the source (because the HTML-encoded special characters will be interpreted and rendered out), if you take a look at the source code you'll see the encoding at work:
$value = '<script>alert('TROUBLE HERE');</script>';
echo filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS);
It converts the special characters into their HTML-encoded selves:
<script>alert('TROUBLE HERE');</script>
FILTER_SANITIZE_EMAIL: This filter does exactly what one would think it does. It removes any characters that are invalid in e-mail addresses (like parentheses, brackets, colons, etc). For example, let's say you accidentally added parentheses around a letter of your e-mail address (don't ask how, use your imagination):
$value = 't(e)st@example.com'; echo filter_var($value, FILTER_SANITIZE_EMAIL);
It removes those parentheses and you get your beautiful e-mail address back:
test@example.com
This is a great filter to use on e-mail forms in concert with FILTER_VALIDATE_EMAIL to reduce user error or prevent XSS-related attacks (as some past XSS attacks involved the returning of the original data provided in a non-sanitized e-mail field directly to the browser).
FILTER_SANITIZE_URL: Similar to the e-mail address sanitize filter, this filter does exactly what one would think, as well. It removes any characters that are invalid in a URL (like certain UTF-8 characters, etc). For example, let's say you accidentally added a "®" into your website's URL (again, don't ask how, pretend a velociraptor did it):
$value = 'http://net.tuts®plus.com'; echo filter_var($value, FILTER_SANITIZE_URL);
It removes the unwanted "®" and you get your handsome URL back:
http://net.tutsplus.com
FILTER_SANITIZE_NUMBER_INT: This filter is similar to the FILTER_VALIDATE_INT but instead of simply checking if it is an Integer or not, it actually removes everything non-integer from the value! Handy, indeed, for pesky spambots and tricksters in some input forms:
$value01 = '123abc456def'; echo filter_var($value01, FILTER_SANITIZE_NUMBER_INT); echo '<br />'; $value02 = '1.2.3.4.5.6.7.8.9'; echo filter_var($value02, FILTER_SANITIZE_NUMBER_INT);
Those silly letters and decimals get thrown right out:
123456 123456789
FILTER_SANITIZE_NUMBER_FLOAT: This filter is similar to the FILTER_VALIDATE_INT but instead of simply checking if it is an Integer or not, it actually removes everything non-integer from the value! Handy, indeed, for pesky spambots and tricksters in some input forms:
$value01 = '123abc456def'; echo filter_var($value01, FILTER_SANITIZE_NUMBER_FLOAT); echo '<br />'; $value02 = '1.2.3.4.5.6.7.8.9'; echo filter_var($value02, FILTER_SANITIZE_NUMBER_FLOAT);
Again, all those silly letters and decimals get thrown right out:
123456 123456789
But what if you wanted to keep a decimal like in the next example:
$value = '1.23'; echo filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT);
It would still remove it and return:
123
One of the main reasons why FILTER_SANITIZE_NUMBER_FLOAT and FILTER_SANITIZE_INT are separate filters is to allow for this via a special Flag "FILTER_FLAG_ALLOW_FRACTION" that is added as a third value passed to filter_var:
$value = '1.23'; echo filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
It would keep the decimal and return:
1.23
Options, Flags, and Array Controls, OH MY!
The flag in this last example is just one of many more options, flags, and array controls that allow you to have more granular control over what types of data gets sanitized, definitions of delimiters, how arrays are processed by the filters, and more. You can find more about these flags and other filter-related functions in the PHP manual's Filters Extension section.
Other Methods of Santizing Data with PHP
Now, we'll go over a few key supplemental methods of sanitizing data with PHP to prevent "dirty data" from wreaking havoc on your systems. These are especially useful for applications still running PHP 4, as they were all available when it was released.
htmlspecialchars: This PHP function converts 5 special characters into their corresponding HTML entities:
- '&' (ampersand) becomes '&'
- '"' (double quote) becomes '"' when ENT_NOQUOTES is not set.
- ''' (single quote) becomes ''' only when ENT_QUOTES is set.
- '<' (less than) becomes '<'
- '>' (greater than) becomes '>'
It is used like any other PHP string function:
echo htmlspecialchars('$string');
htmlentities: Like htmlspecialchars, this PHP function converts characters into their corresponding HTML entities. The big difference is that ALL characters that can be converted will be converted. This is a useful method of obfuscating e-mail addresses from some bots that collect e-mail addresses, as not of them are programmed to read htmlentities.
It is used like any other PHP string function:
echo htmlentities('$string');
mysql_real_escape_string: This MySQL function helps protect against SQL injection attacks. It is considered a best practice (or even a mandatory practice) to pass all data that is being sent to a MySQL query through this function. It escapes any special characters that could be problematic and would cause little Bobby Tables to destory yet another school students database.
$query = 'SELECT * FROM table WHERE value='.mysql_real_escape_string('$string').' LIMIT 1,1';
$runQuery = mysql_query($query);
Custom Functions
For many people, these built-in filters and functions are just not good enough. Data validation of some data like phone numbers, zip codes, or even e-mails often requires more strict validation and masking. To do this, many people create custom functions to validate and their data is real. An example of this may be as simple as using a MySQL query to look up the data in a database of known values like so:
function checkZipCode($value) {
$zipcheck = 'SELECT COUNT(*) FROM `database`.`zipcodes` WHERE value="'.filter_var(mysql_real_escape_string($value),FILTER_SANITIZE_NUMBER_INT).'"';
$count = mysql_query($zipcheck);
if($count==1) {
return TRUE;
} else {
return FALSE;
}
}
Other custom functions can be made that do not rely on databases of known values, and can be created by checking magic-quotes, stripping slashes, and escaping for insert into a database:
function cleanString($string) {
$detagged = strip_tags($string);
if(get_magic_quotes_gpc()) {
$stripped = stripslashes($detagged);
$escaped = mysql_real_escape_string($stripped);
} else {
$escaped = mysql_real_escape_string($detagged);
}
return $escaped;
}
The possibilities are endless, especially if you integrate regular expressions, but for most occasions, the PHP Filters Extension should do the trick.
- Follow us on Twitter, or subscribe to the Nettuts+ RSS Feed for more daily web development tuts and articles.
Related Posts
Check out some more great tutorials and articles that you might like
Plus Members
Source Files, Bonus Tutorials and
More for $9 a month for all TUTS+
sites in one subscription.











User Comments
( ADD YOURS )Brian Klepper September 15th
You covered some nice points thanks!
( )Yigit Ozdamar September 15th
Woow! I wasn’t know that! Thanks mate!
( )Marc September 15th
Ehm… some of the example codes have the wrong filters in them
( )Jeffrey Way September 15th
Thanks! I’ve updated the article.
( )Jarryd September 15th
In the examples “FILTER_VALIDATE_EMAIL”, “FILTER_VALIDATE_FLOAT”, “FILTER_VALIDATE_INT”, “FILTER_VALIDATE_IP” and “FILTER_VALIDATE_URL” you are still using “FILTER_VALIDATE_BOOLEAN”.
Woops?
( )Jeffrey Way September 15th
Fixed.
( )Jarryd September 15th
Awesome
Thanks, Jeffrey
Benjamin Reid September 15th
Very nice explanation, is there an advantage over using this rather than Regular Expressions?
By the way, I think you have forgot to change some of the code examples for : ‘FILTER_VALIDATE_IP’, ‘FILTER_VALIDATE_INT’ and ‘FILTER_VALIDATE_URL’
( )Jeffrey Way September 15th
Fixed.
( )dtbaker September 15th
Nice tutorial!
In FILTER_VALIDATE_BOOLEAN example $value02 should probably be something different to $value01?
( )Scott September 15th
yeah i was thinkin that too.
( )krike September 15th
yes should normally be set to FALSE. in the example it would still return TRUE
Michael Owens September 15th
Yes; it should have said the following:
1. $value01 = TRUE;
2. if(filter_var($value01,FILTER_VALIDATE_BOOLEAN)) {
3. echo ‘TRUE’;
4. } else {
5. echo ‘FALSE’;
6. }
7. echo ”
8. $value02 = FALSE;
9. if(filter_var($value02,FILTER_VALIDATE_BOOLEAN)) {
10. echo ‘TRUE’;
11. } else {
12. echo ‘FALSE’;
13. }
which would return the output below:
—-output begins—-
TRUE
FALSE
—-output ends—-
Unfortunately, I wrote this article amidst a family crisis from the hospital and a number of copy/paste code replacements didn’t make it into my final revision.
Apologies all around.
( )Michael Owens September 15th
Note: apparently, the comments section removed the two br tags in the echo on line 7.
Daniel September 15th
Nice article. I’ll try the filters in my next project. Thanks!
( )Martyn September 15th
Nice tut! Very Informative
( )Simon September 15th
Thanks for the article. Filters aren’t something new so it was about time to have such an article on nettuts !
( )Nice work.
Felix September 15th
Great article.
Check your code segments…it seems the copy&paste devil hit you at some segments!
( )Fab September 15th
Thannks for dis great article. Nice Informations..
( )Julius Beckmann September 15th
Just a few hints for your “Custom Functions”:
// Your function does not work, you forgot to use mysql_fetch_assoc().
// And if a ZIP Code is > 1 times in Database, we will get FALSE.
// Also this if ... return true else return false is way to much typing.
function checkZipCode($value) {
$zipcheck = 'SELECT COUNT(*) AS count FROM `database`.`zipcodes` WHERE value="'.filter_var(mysql_real_escape_string($value),FILTER_SANITIZE_NUMBER_INT).'"';
$count = mysql_fetch_assoc(mysql_query($zipcheck));
return (@$count['count'] > 0);
}
// A Version of your function with less lines and faster execution.
( )function cleanString($string) {
$detagged = strip_tags($string);
if(get_magic_quotes_gpc())
$detagged = stripslashes($detagged);
return mysql_real_escape_string($detagged);
}
xnt14 September 15th
umm, your digg URL is broken, just pointing that out
( )erkasoft web tasarim September 15th
nice article. thanks
( )firmalar September 15th
Try “mail@mail” with FILTER_VALIDATE_EMAIL
( )Gordejev September 15th
Thank you for useful information.
( )I take very pleased.
jigish September 15th
thanks for the filters info
( )Michael September 15th
Great tut! I wasn’t aware of those filters. Thanks!
( )David September 15th
Good information to have on PHP. Thank you!
( )Julius September 15th
Very informative!. Many programmers are not aware of performing security in their coding specially when building an app that has time constraints.
( )krike September 15th
Thanks a lot for sharing :p I used preg_match and regex to validate… took me days to get it right and still doesn’t work like it should.
( )Michael Owens September 15th
There’s also a filter called “FILTER_VALIDATE_REGEXP” that will specifically validate against a custom Perl-compatible regular expression. I did not go over this in the tutorial as some hosts have this filter disabled, but it works similar to the others but with the addition of the regex passed to the filter as an option like so:
filter_var($variable,FILTER_VALIDATE_REGEXP,$regex)
where $variable is the variable you want to validate and $regex is a Perl-compatible regular expression (i.e. like that used in preg_match)
( )Juan C Rois September 15th
Although I’ve used some of this filters before, this article made me realize that I should be using them more often in my scripts.
Thanks, great article
( )Neil September 15th
Wonderful tutorial. I’d been looking for something just like this recently.
Keep up the good work.
( )Baz September 15th
About the last part on checking if magic quotes are on: In the php manual it states that relying on magic quotes is a security hazard and therefore you should always turn it of (in php.ini or in a htaccess file).
From php 6 I believe it doesn’t exist anymore.
( )Scott Radcliff September 15th
Checking for errors and using descriptive helpful error messages are one of the most overlooked additions to a website . There are some great tips here. I have to admit I am not familiar with PHP filters. I have had my head buried in Ruby. Are filters relatively new?
( )Michael Owens September 15th
Data Filters in PHP arrived in PHP 5.2.0 back in 2006, the last major release of PHP prior to this summer (5.2.8/5.2.9/5.2.10 were all bugfix and security updates). PHP 5.3.0 was released this summer.
Generally speaking, the better web hosting companies that I have looked into are using 5.2.10, with some upgraded to 5.3.0; there is, unfortunately, a large number of PHP 4 legacy web hosting systems out there, though. It’s really rare to find a PHP 5 web host that is running 5.0.0-5.1.* because of the security fixes in 5.2.8/5.2.9/5.2.10
( )Timbronze September 15th
Wow, I didnt have a clue about these, I will certainly be looking into them further, they could be very useful.
( )Webhostright September 15th
Thanks for a good explanation on filters, im just learning php at the moment so i still have to learn a lot more.
( )Daniel Whyte September 15th
cool, thanks
( )Myfacefriends September 15th
this is awesome! thanks
( )Drew Douglass September 15th
So glad to see someone taking advantage and teaching how to use filters in php. All too often, I see horribly hacky regular expressions or lengthy if statements where a simple filter check (such as FILTER_VALIDATE_EMAIL) would have solved the problem. Great stuff.
( )Isaiah September 17th
Actually FILTER_VALIDATE_EMAIL isn’t very good. It’s much better to use regex to valid email addresses. See http://codepad.org/lCqSNfs7 and http://fightingforalostcause.net/misc/2006/compare-email-regex.php for more details about validating email addresses.
( )Nikola Malich September 15th
Great explanation of filters, thanks!
( )Brad September 15th
I use Validate and Sanitize all the time now. The only problem is I still catch myself santizing strings that may have html (such as links) in them and the links are gone! There are still times to use regex, in fact you can use regex with the filters
FILTER_VALIDATE_REGEXP
Great stuff, the more people know about the filters the better the web will be, and they are so easy to use
( )Montana Flynn September 15th
How would you validate a form field in a basic contact form? Everything I try breaks my form.
( )Arafat Rahman September 15th
Learned lot of new things
( )Simon September 15th
And here I spent a couple of days ago getting my head around a regex filter for e-mail addresses. I’m now going to simplify and update my code.
Thanks for these tips.
( )Bryan Broussard September 15th
Great Tutorial.
But the BOOLEAN returns TRUE in the version posted.
( )Narendra September 15th
Really a nice article
( )Mujtaba September 16th
oo how i loved that DROP TABLE image!
( )Csaba September 16th
Cool, I’ll have to move to PHP 5.2.0, didn’t know about these filters
( )Robert Hofmeyr September 16th
Just a comment… FILTER_SANITIZE_NUMBER_INT allows signed integers (i.e. +/- won’t be stripped). It also returns a string and NOT an integer. For this reason, I prefer casting using (int) $_POST['var'] and assume that 0 is an invalid entry when dealing with Integer validation.
( )Niklas September 16th
Sweet! Glad this got posted! I have been using filter_var for quite some time now and it’s working great.
( )Web 2.0 Tools September 16th
very useful tutorial
( )Jan Pieper September 16th
In section “Other Methods of Santizing Data with PHP” you are using a variable inside of single-quotes. I don’t think this is what you wanted.
( )Michael Mokrysz September 16th
As far as I know, the url filtering via filter_var is pretty much just like running it through parse_uri and seeing if it gives an error. If you think about how hard it is to make parse_uri just return FALSE then you can probably understand why it’s not much use.
( )Brian Temecula September 16th
I’ve been using php’s PECL filter for a long time… well ever since I read Larry Ullman’s PHP Advanced book. It’s good to see a tutorial here about this, because it is easy and effective.
( )Adam September 16th
Thanks for the great explanations of filters. I’ve been filtering my data for quite some time now and was really happy when PHP built out these functions. I’m very impressed with all the filters except for the URL handling. This is a warning to anyone wanting to filter URLs.
I came across an old page (not written by me) on the site I manage that takes a URL as unfiltered input and writes it out to the screen unescaped in a link. This is very vulnerable to XSS attacks. So I added filtering and escaping to the code, but realized it didn’t completely fix the problem.
Take the following code:
“>alert(123)
This dumps out the obviously malformed URL. I know PHP’s standard filtering can’t be the end-all-be-all for data input, but I hope the URL filter can be improved.
( )Adam September 16th
Sorry, the code didn’t copy the way I expected it to. Let’s try this again:
<?php
( )$url = ‘http://>"><script>alert(123)</script><".mysite.com/page.html’;
$url_san = filter_var($url, FILTER_SANITIZE_URL);
var_dump($url_san);
if (filter_var($url_san, FILTER_VALIDATE_URL))
var_dump($url_san);
else
echo ‘Fail’;
?>
Can Berkol September 16th
Good post. We often use custom function and extra parameter checks for each function as a development standard. It usually means few more lines of coding but it is worth for increased security.
( )Dustin Lakin September 16th
Always a big fan of security articles, thanks for this.
( )Jacob Fogg September 16th
Thanks for the article! I am ashamed to admit how many of these I have manually coded =/ no more! =)
On a side note, your code for “What filters do I have” is backwards… The names are dropping in the ID column and vice-verse. Thanks for this post!
( )Stuart September 17th
Brilliant Tutorial, there is a lack of quality articles on PHP security on the web
( )Steven Aiello September 17th
This is a really good quality tutorial, very practical for every day use. Great job.
( )Pavlow Vinelli September 18th
Verry good tutorial thank for all
( )Drazen Mokic September 19th
Nice, i realy love the thumbnail “php super clean” image
( )Vahid Hallaji September 22nd
Perfect
( )Cyril A. Karpenko September 23rd
*ROFL*
How many letters…. I think validators ( as in Zend Framework, for example ) and OOP rescue poor people from inviders and in a future – from PHP.
( )Burak Bakırcı September 24th
Thanks Michael!
( )Ed Chan September 30th
Good call!
( )orkun October 3rd
very useful thanx for this..
( )MEM October 6th
I’m trying to use the filter function on int.
The point is to accept only numbers on a input field.
I have this:
if (!filter_var(filter_var($phone, FILTER_SANITIZE_NUMBER_INT), FILTER_VALIDATE_INT))
{
$erros['phone'] = ‘Invalid Phone.’;
}
But I’m getting this:
If I put on the field “aaaaasfa” o error shows.
If I put on the field “24525232″ o error doesn’t show.
If I put on the field “2323Aasda” the error DOES NOT show as well. When I was expecting him to show!
I’ve also tried like this:
if (!(filter_var(filter_var($phone, FILTER_SANITIZE_NUMBER_INT), FILTER_VALIDATE_INT)))
{
$error['phone'] = ‘Invalid Phone.’;
}
No luck either.
Anyone kind to elucidate this newbie that is not so clean?
Kind regards.
( )MEM October 6th
Solved. We just need to validate first, and sanitize later.
If we sanitize first, the validation will pass.
A more proper newbie thankfull for this article,
( )MEM
Jay November 16th
Very nice an inforamtive article.
Thanks for that!
I’m just writing a new class for contact form validation using php5.2 and till know I haven’t used the filter functions of php 5.2 to sanitize input data, but I will give it a try.
( )