PHP Built in Input filtering

Security becomes the top priority (or activity) of many PHP developers. Its place and importance keeps growing in every single project, open source or commercial. Every conference provides a talk about security and you can read PHP security on the magazine cover pages.

Security in PHP application is a large topic. This article explains one of the most important part of any security policy: the input or data filtering.

General security topics like XSS, SQL injections and other dangerous attacks will not be discussed here, take a look at the end of this article for a small list of resources.

Don’t trust external data

Practically all applications (web, desktop, console) depend on external input to create output or to start an action. This input comes from a user or another application (web services clients, bots, scanner, etc.). The rule #1 of every developer (you all know it, but it does not hurt to write it down once more) should be:

Filter All Foreign Data

Input filtering is one of the cornerstones of any application security, independently of the language or environment. PHP provides a wide range of tools and functions to filter or validate data, but unlike other languages, it does not have any standard functions to filter data (like cgi for perl). The new Filter extension fills this gap.

What’s foreign data?

  • Anything from a form
  • Anything from $_GET, $_POST, $_REQUEST
  • Cookies ($_COOKIES)
  • Web services data
  • Files
  • Some server variables (e.g. $_SERVER['SERVER_NAME'])
  • Environment variables
  • Database query results

Filter supports get, post, cookies, server and environment variables as well as defined variables (server and env support may not work in all sapi, for filter 0.11.0 or php 5.2.0).

Why Filter?

To test, validate and filter user input or custom data can rapidly be annoying and repetitive task. It is easy to forget a test or write an incomplete regular expression. The Filter extension aims to make data filtering less painful as this simple example shows:

Check two integer _GET input values:

<?php
 
if (isset($_GET['mode'])) {
    if (!is_numeric($_GET['mode'])) {
        echo "The 'mode' argument must be a valid integer.<br />";
        exit();
    }
    $mode = (int)$_GET['mode'];
} else {
    echo "The 'mode' argument is missing.<br />";
    exit();
}
 
if (isset($_GET['type'])) {
	 $type = (int)$_GET['type'];
	if (!is_numeric($_GET['type']) ||
		(is_numeric($_GET['type']) && $type >= 3 && $type <= 10)) {
        echo "The 'type' argument must be an integer between 3 and 10.<br />";
        exit();
	} else {
	}
    $mode = $_GET['type'];
} else {
    echo "The 'type' argument is missing.<br />";
    exit();
}
echo "Ok.<br />";
?>

and using Filter’s filter_input:

<?php
 
$mode = filter_input(INPUT_GET, 'mode', FILTER_VALIDATE_INT);
$type = filter_input(INPUT_GET, 'type', FILTER_VALIDATE_INT, array('options'=>array('min_range'=>3, 'max_range'=>10)));
 
if (is_null($mode)) {
    echo "The 'mode' argument is missing.<br />";
    exit();
} elseif ($mode === false) {
    echo "The 'mode' argument must be a valid integer.<br />";
    exit();
} else {
	echo "mode is: $mode.<br />";
}
 
if (is_null($type)) {
    echo "The 'type' argument is missing.<br />";
    exit();
} elseif ($type === false) {
    echo "The 'type' argument must be an integer between 3 and 10.<br />";
    exit();
} else {
	echo "type is: $type.<br />";
}
?>
 

How does it work?

The process to transform an input request to a set of user land variables is done by the SAPI layer. Without going into the details, the SAPI layer is the interface between the wild world and the PHP engine. The engine fetches external data (ENV, SERVER, COOKIE, GET or POST)
from the SAPI and transforms them into the well known super global or uses them in the related functions like getenv.

Filter is active both at the SAPI level and in the engine. SAPI supports custom filtering operation, Filter functions are called for each external data being processed by the Engine. It is done before the script gets the hand on it. How the SAPI filter will process the data is defined by the default filter, configurable using your php.ini.

Given a simple POST request like:

POST /myform.php?myfield=<script>hola</script>

The diagrams below explain the difference between a normal operation (like php 5.1, without Filter enabled) and a PHP including Filter support:

 

Prerequises

Filter works out of the box from PHP version from 5.1.0 or ealier. The extension is bundled in PHP 5.2.0 or earlier.

Installation

PHP 5.2.0 or earlier has Filter bundled and enabled by default. There is no need to manually install it.

Unix/Linux:

$ pecl install filter

or

$ wget  http://pecl.php.net/get/filter
$ tar xzf filter
$ cd filter-0.11.0
$ phpize
$ ./configure
$ make
$ make install

Windows:

Download the filter.dll for your PHP version on http://pecl4win.php.net

 

For all platforms, add extension=filter.so to your php.ini and restart your web server.

For more informations about PECL installation procedures, please read the PHP manual.

General considerations

Filter knows two kinds of filter:

  1. santizing filters
    • Allow or disallow characters in a string
    • Does not cate about the data format
    • It always returns a string
  2. logical filters
    • Strong analysis of the data
    • Knows the formats
    • Returns the expected type on success

Filters are invoked using one of these functions:

  • filer_input, fetches one input variable
  • filter_input_array, fetches many input variables in a single call
  • filter_var, filter one variable
  • filter_var_array, filter many variables in one call

The value is returned filtered and using the right type on success, FALSE if the filter fails (bad chars, out of range, …) and NULL if the variable is not set. Using the optional flag FILTER_NULL_ON_FAILURE, the behavior can be reversed, it will return NULL on failure and FALSE if the variable is not set.

With these three different states, it becomes easy to get rid of the isset or is_numeric mess.

A simple form using logical filter

<html>
<head></head>
<body
    <form action="example04.php" method="post" >
    Enter your age: <input name="age" size="2">
    <input type="submit" name="submit" value="Go">
    </form>
</body>
</html>

And the little script to process it:

<?php
if (!filter_has_var(INPUT_POST, 'submit')) {
    echo "form";
    // include the form.
}
 
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT);
if (is_null($age)) {
    echo "The 'age' field is required.<br />";
} elseif ($age === FALSE) {
    echo "Please enter a valid age.<br />";
} else {
    echo "Welcome.<br/>";
}
?>
 

filter_has_var tests if a given variable is set or not. It does not make any validation but only tells whether a variable is set. It is the equivalent of isset($_POST['submit']). filter_input fetches one single value and returns it filtered. In this example an integer is expected.

If this script displays the last “Tintin” cartoon, the age must be between 7 and 77 :) . The numeric filters options accept a minimum and maximum range:

<?php
if (!filter_has_var(INPUT_POST, 'submit')) {
    echo "form";
    // include the form.
}
$options = array('options'=> array('min_range'=>7, 'max_range'=>77));
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, $options);
 
if (is_null($age)) {
    echo "The 'age' field is required.<br />";
} elseif ($age === FALSE) {
    echo "You must be enter a valid age and be between 7 and 77 years old.<br />";
} else {
    echo "Welcome.<br/>";
}
?>

To add another field for example an email, the procedure is identical:

$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);

Just like the other field, $email will be FALSE if the email is invalid and NULL if the email field is missing (for example a lazy spam bot did not detect it).

A simple form using a sanitizing filter

<html>
<head></head>
<body
    <form action="example05.php" method="post" >
    Enter your name: <input name="name" size="50">
    <input type="submit" name="submit" value="Go">
    </form>
</body>
</html>

The following filter_input call will clean up the “name” variable and returns it useable :

<?php
if (!filter_has_var(INPUT_POST, 'submit')) {
    echo "form";
    // include the form.
}
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_SPECIAL_CHARS);
if (is_null($name)) {
    echo "The 'name' field is required.<br />";
} else {
    echo "Hello $name.<br/>";
}
?>
 

If the “name” contains a value similar to:

Johnny Weißmüller <b>Jr</b>

FILTER_SANITIZE_SPECIAL_CHARS will return:

Hello Johnny Weißmüller <b>Jr</b>.

A nicer filter for this field would be:

$name = filter_input(INPUT_POST,
                     'name',
                     FILTER_SANITIZE_STRING,
                     FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW);

and it returns

Hello Johnny Wei&#223;m&#252;ller Jr.

The sanitizing filters accept many options and flags. In this example, we use the “string” filter (also called “stripped”) which accepts low or high values stripping. A complete list of filters and flags is available in the Filter manual.

How to Fetch all values in one call?

<html>
<head></head>
<body
    <form action="example07.php" method="post" >
    Name: <input name="name" size="50"><br />
    Email: <input name="email" size="50"><br />
    Homepage: <input name="homepage" size="50"><br />
    Age: <input name="age" size="4"><br />
    Income: <input name="income" size="50"><br />
    Your two favourites languages:
    <select name="favourites[]" size="6" multiple>
        <option value="haskell">haskell</option>
        <option value="r">R</option>
        <option value="lua">Lua</option>
        <option value="pike">Pike</option>
        <option value="rebol">Rebol</option>
        <option value="php">PHP</option>
    </select><br />
    <input type="submit" name="submit" value="Go">
    </form>
</body>
</html>

and the script to process it:

<?php
if (!filter_has_var(INPUT_POST, 'submit')) {
    echo "form";
    // include the form.
}
 
$defs = array(
    'name'       => array('filter'=>FILTER_SANITIZE_STRING,
                    'flags' => FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW),
    'email'      => FILTER_VALIDATE_EMAIL,
    'homepage'   => FILTER_VALIDATE_URL,
    'age'        => array(  'filter' => FILTER_VALIDATE_INT,
                            'options'=> array('min_range'=>7, 'min_range'=>77)),
    'income'     => FILTER_VALIDATE_FLOAT,
    'favourites' => array(
                        'filter' => FILTER_SANITIZE_STRING,
                        'flags'  => FILTER_REQUIRE_ARRAY
                    ),
          );
 
$input = filter_input_array(INPUT_POST, $defs);
 
if ($input['age'] === FALSE) {
    exit("You must be between 7 and 77 years old.");
}
 
if (is_null($input['favourites'])) {
    exit("You have to choose two or more languages.");
}
 
if (!in_array('PHP', $input['favourites'])) {
    exit("You don't like PHP!");
}
 
/*Other checks for required values */
?>
 

As the script shows, fetching all values you need is as easy as fetching a single value. The only difference is how options or flags are given. An array must be used as soon as you need options or flags.

It can look overkilled to use such array, but it amazingly increases the readability of the input parsing code in a script. Adding, removing or editing input rules can be done in seconds.

Complex processing using callback

Instead of doing a simple string validation for the “favourites”, a user function will be used. The “options” argument is used to define the callback using the same syntax as the PHP call_user_func.

<?php
class language {
    function __construct($name) {
        $this->name = $name;
    }
}
 
function check_languages($var) {
    static $called = 0;
    $called++;
    echo "called: $called: $var<br />";
    $var = filter_var($var, FILTER_SANITIZE_STRIPPED);
    $l = new language($var);
    return $l;
}
 
if (!filter_has_var(INPUT_POST, 'submit')) {
    echo "form";
    // include the form.
}
 
$defs = array(
    'name'       => array('filter'=>FILTER_SANITIZE_STRING,
                    'flags' => FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW),
    'email'      => FILTER_VALIDATE_EMAIL,
    'homepage'   => FILTER_VALIDATE_URL,
    'age'        => FILTER_VALIDATE_INT,
    'income'     => FILTER_VALIDATE_FLOAT,
    'favourites' => array(
                            'filter' => FILTER_CALLBACK,
                            'options'  => 'check_languages'
                    ),
          );
 
$input = filter_input_array(INPUT_POST, $defs);
 
if ($input['age'] === FALSE) {
    exit("You must be between 7 and 77 years old.");
}
 
if (is_null($input['favourites'])) {
    exit("You have to choose two or more languages.");
}
 
echo "Your favourite languages:<br /><ul>";
foreach ($input['favourites'] as $l) echo '<li>' . $l->name . "</li>";
echo '</ul>';
?>
 

The function will be called once if the variable is a scalar; if the variable is an array, it will be called once for each element.

Filter does not sanitize or validate the input before or after the callback. But filter_var can be used inside your callback function or method as shown in this example.

Why no OO?

Filter does not provide any object oriented interface. The current API is flexible enough to add any kind of filters, support unicode (more on this topic in another article) or to integrate into your favourite framework or MVC application.

If someone wrote a generic OO wrapper for the filter function, I would be happy to include it in the examples directory, but do not wait an OO interface, it is not going to come anytime soon.

Default filter, PHP 5.1.x and shared host

The default filter is set to unsafe_raw in PHP 5.2.0 or later. It will not be set to any other default filter by default. An attempt has been made to set it to string, but it breaks way too much applications and it makes the migration process a pain. If you plan to use it, be sure to have first fixed all your applications or loudly warned your users.

Filter works out of the box on PHP 5.1.x. I would recommend to install it by default on any PHP 5.1.0 (without default filter). I’m sure all applications will soon rely on it. It does not solve all security issues but it gets rid of all common mistakes or bad usages.

Filter Links

Other resources about PHP and Security

Published: October 31st, 2006 at 8:53
Categories: Tutorials
Tags: ,

21 comments to “PHP Built in Input filtering”

Regarding this example:
$name = filter_input(INPUT_POST, ‘name’, FILTER_SANITIZE_SPECIAL_CHARS);
if (is_null($name)) {
echo "The ‘name’ field is required.<br />";
} else {
echo "Hello $name.<br/>";
}

I will not ever want to SANITIZE_SPECIAL_CHARS while getting input data. Because this action is surely output related and I wish to operate with non-sanitized data until outputting. So instead of the example I would use something like this:

$name = filter_input(INPUT_POST, ‘name’, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); // strip invalid characters that shouldn’t be in names, but don’t prepare for output
if (is_null($name)) {
echo "The ‘name’ field is required.<br />";
} else {
$nameOutput = filter_data($name, FILTER_SANITIZE_SPECIAL_CHARS); // prepare data for html output
echo "Hello $nameOutput.<br/>";
}

_____anonymous_____
November 1st, 2006 at 2:05 am

"PHP 5.2.0 or earlier has Filter bundled and enabled by default. There is no need to manually install it."

Is that correct? Should it not read "5.2.0 and later"?

Thanks for the notice, I meant 5.2.0 or later. Fixed now (should be visible online shortly)

Yes, this code is only an example to explain how this kind of filter works. There is many filters for all nearly all needs.

In the paragraph "A simple form using logical filter", second code block. Shouldn’t it be

array(‘min_range’ => 7, ‘max_range’ <= 77)

Alex

"max_range" – yes, it’s a typo.
"<=" – strange array() syntax, isn’t it? :)

if (!in_array(‘PHP’, $inputs['favourites'])) {

should be

if (!in_array(‘PHP’, $input['favourites'])) {

Please guys, this API is pain. First of all its a mix of two concepts. Filters that alter incomming data and rules that validate input data.

This API will not make your input filtering easier. Actually its going to make it more complicated. Imagine a simple example:

If I want to validate an simple input. It must be a number and it must be between 1 and 20. In this API I will create 2 callback functions (regex and range) or use existing ones. So far so good. But now starts the pain. User enters input 21 and after validation you get resulting value false. Now what happened? Which validation failed? You don’t know! You have to do validation for this field again, just to display the correct error message. So this API actually solves nothing.

The reason not to use OO and trying to mimic it with some sort of nasty arrays with callbacks and constants is absolutely funny. Now for all those PHP devs that mean that OO is just bloated stuff, look at this OO code and say that it’s not easier to understand than examples in this filtering introduction.

$defs = new InputValidation();
$defs->addFilter(‘number’, new TrimFilter()); // trim whitespaces
$defs->addRule(‘number’, new RegexRule(‘/^[0-9]+$/’, ‘Input "%s" in not a number!’));
$defs->addRule(‘number’, new RangeRule(1, 20, ‘Number %d is not between %d and %d!’));

// some tests
$results = $defs->validate(array(‘number’ => ‘ aa ‘));
$results['number']['value'] == false;
$results['number']['errors'] == array(‘Input "aa" in not a number!’);

$results = $defs->validate(array(‘number’ => ‘ 30 ‘));
$results['number']['value'] == false;
$results['number']['errors'] == array(‘Number 30 is not between 1 and 20!’);

$results = $defs->validate(array(‘number’ => ‘ 16 ‘));
$results['number']['value'] == ’16′;
$results['number']['errors'] == false;

Let me try to to show you how to use filter for your example (using a variable instead of input):

$res = filter_var($var, FILTER_VALIDATE_INT, array(‘options’=>array(‘min_range’=>1, ‘max_range’=>20)));

if (!$res) {
echo “myvar must be a number between 1 and 20”;
}

I understand this code in half a second. And the error message is, imho, clearer. There is only one error message, but I’m not sure the goal of having 20 error messages for one invalid input, especially for a numeric input.

Actually the only thing you seem to dislike is the usage of a procedural API with only scalars or array of scalars as arguments instead of an OO API with numerous classes and methods (per rule, per role, etc..).

Filter is flexible enough to allow you to wrap it in such complex set of classes, just do it if you need it.

Here is simple wrapper class for validation, which I made for my own input processor class.

class PhpFilter_Rule{

protected $errorMsg = ”;
protected $ruleId = null;
protected $params = array();
public $isValid = false;

function __construct($type,$flags=null,$options=null,$errorMsg=’Invalid value!’){
if (!$this->ruleId = filter_id($type)){
throw new PhpInput_Exception(‘Rule not found’);
}
$this->errorMsg = $errorMsg;
$flags && $this->setFlags($flags);
$options && $this->setOptions($options);
}
function setErrorMsg($msg){
$this->errorMsg = $msg;
}
function setOptions($options){
if (!is_array($options)){
$options = array($options);
}
$this->params['options'] = $options;
}
function setFlags($flags){
$this->params['flags'] = $flags;
}
function getErrorMsg(){
return $this->errorMsg;
}

function validate($value){
return $this->isValid = filter_var($value,$this->ruleId,$this->params);
}
}

Usage:
$input = new InputProcessor();

$rule = new PhpFilter_Rule(‘int’,FILTER_FLAG_ALLOW_HEX,array(‘max_range’=>1000,’min_range’=>1));
$rule->setErrorMsg(‘Value must be a number between 1 and 1000 dec or hex’);

$input->addRule(‘field’,$rule);

"Actually the only thing you seem to dislike is the usage of a procedural API with only scalars or array of scalars as arguments instead of an OO API with numerous classes and methods (per rule, per role, etc..)."

No. There is actually a 1 to 1 mapping between your constants and my class names. A 1 to 1 mapping between your santitation filters and my Filters. And finaly a 1 to 1 mapping between your logical filters and my Rules. So the is no overhead complexity in this direction. You like procedural array and OO guys like objects. I don’t really wanted to start a flame about OO versus procedural versus … sorry for that.

"I understand this code in half a second. And the error message is, imho, clearer. There is only one error message, but I am not sure the goal of having 20 error messages for one invalid input, especially for a numeric input."

The problem is not with numerous error messages. Problem is you can have only one validation rule on one variable.

Simple and real life example:
I want a validation for a form creating new articles. Article heading must not be empty, must contain only url-safe characters and there is not an article with that name already in DB. I want to display error message for that validation that failed. A message like "Article heading must not be empty, must only contain characters a..z and must be unique." is just not user-friendly. You have to admit that.

I think you can’t do this easily with this API. Can you?

“A message like “Article heading must not be empty, must only contain characters a..z and must be unique.” is just not user-friendly. You have to admit that”

You can define this message, just like “Must be a number and be between 7 and 77.”. I only don’t see the point to use such complexity for simple needs. It is off the goals of this extension.

“The problem is not with numerous error messages. Problem is you can have only one validation rule on one variable.”

I understand that. You need three rules? Call three times filter_input.

That said, I find a bit pointless to apply three filter (no matter how) to validate an integer as you show in your example. The filter API provide a way to do validations in one function call. Please understand that (it is fast, small and simple to use) :)

“I think you can’t do this easily with this API. Can you?”

You can do it easily. Some frameworks do it already (afair eZ Components use filter). It is just not the goal of the extension to provide a way to deal with error messages, use object to define simple rules or input.

Now about proving you wrong by writing an OO interface, it is a no-no, I find such interfaces “overdesigned” and really pointless for input validation. But as I said in the article, feel free to provide as example.

"You need three rules? Call three times filter_input.

That said, I find a bit pointless to apply three filter (no matter how) to validate an integer as you show in your example. The filter API provide a way to do validations in one function call. Please understand that (it is fast, small and simple to use) :) "

Ok, so instead of calling it once a getting error message for rule that failed I have to call it three times. This is what you call simple?

Ok, you are really right that I can wrap that in some other API and call it with single call. But what I just cannot understand why this is not in the basic package. All examples in this tutorial deal with error messages, isn’t that a clear sign that error messages and validation are closely tight together? Why are you so utterly trying to separate two things that naturally belong together?

"Now about proving you wrong by writing an OO interface, it is a no-no, I find such interfaces overdesigned and really pointless for input validation. But as I said in the article, feel free to provide as example."

Overdesigned? This is interesting. I showed you in my post earlier that there is a bidirectional 1-to-1 mapping between filter API and my OO API. So if you are talking about something overdesigned there must be something equally overdesigned in your filter API too.

Don’t forget that probably all OO guys have a procedural programming background. Procedural paradigm is a subset of object-oriented paradigm. Objects are just a way to get closer to human language a so they are easier to understand for people.

I have seen this many times, procedural guys just don’t understand OO guys, but its not true the other way. The only thing that OO guys don’t understand about procedural guys is why are not moving towards OO. Have you ever tried it? How long have you tried? Do you know what polymorphism and encapsulation is good for? I know from my own experience that learning OO is really hard. It really is a different art of thinking, not just syntax sugar. But once you get it, you will clearly see its the better way and never look back.

I don’t think that I am going to take you on bright side of OO with this simple post. ;-) That’s not the point.

The main point is that this API is trying to separate error messages and validation that in real world naturally belong together. If you don’t that think that, look again at examples in this tutorial.

I can also see some cases where you don’t need error messages and want to fail silently. That’s fine, you can do that with my API. Just omit the error messages in Rule classes. But most real world forms, validations will always have to end up with some error message. Once again examples in this tutorial are a great example of that.

Now not only to criticize, I don’t think that the whole idea is wrong. I just think the API needs some tweaking to get it right and closer to real needs. With OO even closer to human language. You have probably done a great job in various sanitizing validators (filters) and logical validators (rules). Big thanks for that.

We are on the same side of barricade. My intentions are to make PHP better. I want to collaborate.

“The main point is that this API is trying to separate error messages and validation that in real world naturally belong together. If you don’t that think that, look again at examples in this tutorial.”

I give you a scoop: The goal of this tutorial is to explain how to use the filter functions and I think it does it well. The examples have some messages as example, to have something to test locally and play with, no more no less.

“We are on the same side of barricade. My intentions are to make PHP better. I want to collaborate.”

I prefer sandboxes, more fun :-D

This discussion is a bit off topic. I suggest you to take a look at the various framework, they aim to provide the missing layers.

"I give you a scoop: The goal of this tutorial is to explain how to use the filter functions and I think it does it well. The examples have some messages as example, to have something to test locally and play with, no more no less."

Ok, if I understand this correctly – filter extension is just about getting a value passed through a filter. Right?

I’m going to lower myself to procedural because you seem to be allergic to OO. And again I am going to talk about API.

Why do you introduce constants like INPUT_POST, INPUT_GET, INPUT_COOKIES? How about filter_input($_GET, ‘name’, …) ?

What is filter_has_var(INPUT_GET, ‘name’) ? A longer (and a pretty bad) alias for isset($_GET['name']) every PHP developer understands in split of a second?

If this extension is really only about filtering (no error messages, … just string passing through filters, right?) why do you introduce such things? I thought you wanted to make it simple. All you will ever need is filter_var and this little helper function.

function filter_input($array, $name, $filter, $options = array()) {
return (array_key_exists($name, $array)) ? filter_var($array[$name], $filter, $options) ? null;
}

Now you can do everything in this tutorial, without INPUT_*type constants and all that just by introducing one new function filter_input. Everything else in this API is just a different naming and complicating things that are already solved in PHP.

The Filter extension is the biggest mistake since of the magic_quotes_gpc and register_globals. There are two reasons.

1) Filter is written in C language.

If Filter have been written in PHP, anybody can correct or change it’s behaviour.

Example: in my country, there is convention to write float numbers with comma as decimal separator, somebody writes them with dot. Filter and its FILTER_VALIDATE_FLOAT doesn’t support this.

Another example: FILTER_VALIDATE_EMAIL say this is email: "franta@centrum.cz"@seznam.cz is valid. A this "vfranta@centrum.cz"@seznam.cz (added letter v) not. Is this corrent? I don’t think so. But I cannot corect this behaviour in PHP.

2) Ability to sanitize input data is nonsense! Nonsense, which leads to false sense of security.

There is no need to sanizite input data (striping tags or adding magic quotes). Why? Input data are not output data! It is important to escape output data, due OUTPUT CONTEXT. Is output context HTML? Ok, use htmlSpecialChars. Is output context SQL command? Ok, escape data with propriety function, for example mysql_real_escape_string. Various databases use their own escape method. There is no universal way.

But never sanitize input data! Input data are used for some processing. Sanitizing input data leads to badly findable security mistakes.

Therefore extension Filter is security scrape. First of all for begginers. Don’t use it, please!

“1) Filter is written in C language.”

It is not possible to provide what this extension does in userland. Please read the first paragraphs of this article.

“in my country, there is convention to write float numbers with comma as decimal separator, somebody writes them with dot. Filter and its FILTER_VALIDATE_FLOAT doesn’t support”

Use the decimal filter option.

“Another example: FILTER_VALIDATE_EMAIL say this is email: “franta@centrum.cz”@seznam.cz is valid. A this “vfranta@centrum.cz”@seznam.cz (added letter v) not. Is this corrent? I don’t think so. But I cannot corect this behaviour in PHP.”

It must a be a bug, the regexp is not perfect (which email regexp is…:). You can “fix” it using your own regexp.

Just my 5 cents. I think that idea of standard variable filtering is good, but the syntax is realy ugly. Are you sure there can’t be no other to creating filters not using functions with 4 parameters one of which is an array itself and two other are some STUPID_FOUR_WORDS_CONSTANTS.

_____anonymous_____
May 15th, 2007 at 10:36 am

As commented above, still "PHP 5.2.0 or earlier" exist in "Prerequises" and "Installation". Am I right? It should be replaced to "later".

Hi all:

How would you filter an input that is an array?

ie: <input type="text" name="user[]">

?

I can get the raw post before filter is applied?

My Host provider is using php filter module. Now, my wordpress xmlrpc.php interface is not working.

If I print the contents of php://input

file_get_contents( ‘php://input’ )

it gave me:

h3 class="alDiaTitle"&gt;Intermoda 2009/h3&gt;

instead of:

<h3 class="alDiaTitle">Intermoda 2009</h3>

I don’t know why since the configuration is:

filter.default unsafe_raw

Regards.