Easy transparent PHP input filtering

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.

Leave a comment

Recent Entries

  • Load Balancing with HAProxy

    Load Balancers are some of the most expensive bits of equipment small to medium size sites are likely to buy, even more expensive than database...

  • SixXS IPv6 and CentOS

    I thought its high time I get to spend some time with IPv6 so I signed up for a static tunnel from sixxs.net, apart from...

  • Location aware Bind for RedHat 5.3

    Previously I wrote about RPMs I built to GeoIP enable Bind using the original patches at http://www.caraytech.com/geodns/.I have now refreshed this for the latest CentOS...

  • CentOS 5.3

    CentOS 5.3 was released on the 1st of April, I've since updated a whole lot of my machines to this version and been very happy.There...

  • WIRED UK

    I was quite excited about the new UK edition Wired.  I'm not anymore.I got my first exposure to the Wired while in school in South...

Close