Select Page
NOTE: This is a static archive of an old blog, no interactions like search or categories are current.

I have been working on a site that will have potentially quite a few random third parties accessing it and inserting data into a MySQL database.  I am thus quite keen on a good solid input filtering method for PHP to prevent things like XSS and SQL Injection.

There are several options out there, of the ones I found Inspekt is about the closest match to my way of working, it essentially imports $_GET, $_POST etc and wraps them in an object which you then use to access variables in a filtered method.  It by default then NULLs the original variables so you cannot access them anymore, if backward compatibility is desired it can leave the originals untouched.  Not optimal as this gives an unsafe by default result if you want to maintain backwards compatibility.

Another problem with this approach is that it is a lot of work to change existing code, which you might thing is just par for the course but I was convinced I need to find a way to do so more transparently.

I could for example at program start just walk through the $_GET etc arrays and apply some filtering to them using addslashes() and such but this is very restrictive, what if you need to get it unfiltered, especially if you perform destructive filtering?  How would you go about filtering some variables for phone numbers, some for email addresses etc?

The answer lies in PHP’s new Standard Programming Library, specifically in its ArrayAccess interface, which if you don’t care for older versions of PHP is the way to go.

The basic advantage of this is that you can expose properties of your objects by using array notation rather than object notation:

$result = $foo->getBar();

compared to:

$result = $foo[‘bar’];

Both statements give access to the private variable $bar just using different syntax.  So using this technique we can write a transparent filter for input variables, the basic usage of the final library would be something along these lines:

$_GET = new ArrayArmor($_GET);

print (“Filtered Variable:$_GET[test]<br>\n”);

print (“Unfiltered Variable: ” . $_GET->getRaw(“test”));

A possible output from this script can be seen below:

Filtered Variable: 1234\’;delete from accounts;–
Unfiltered Variable: 1234′;delete from accounts;–

You can see that the default behavior is to protect the input but even for destructive filtering methods the raw unfiltered data would be available if the programmer needed it.  You can provide all sorts of extra methods to validate emails, post codes and such.

A quick and dirty example of a class that provides this kind of filtering can be seen below:


<?
class ArrayArmor Implements ArrayAccess {
    private 
$original;

    function __construct (&$variable) {
        
$this->original $variable;
    }

    function offsetExists($offset) {
            return isset(
$this->original[$offset]);
    }

    function offsetGet($offset) {
        return 
addslashes($this->original[$offset]);
    }

    function offsetSet($offset$value) {
    }

    function offsetUnset($offset) {
    }

    function getRaw($offset) {
        return(
$this->original[$offset]);
    }
}
?>



So that’s it, a simple method that is very easy to put into existing code. This is clearly not a full example as addslashes() is hardly the be-all and end-all of input protection, but if you build on this you can get a very easy to use and flexible input filter that is safe by default.