Did you think your site validated input properly? Think again!

Tags:

You’ve written a PHP based web app, and you’ve made sure it doesn’t cause errors if the user submits unexpected values via any URLs or forms.

But there’s something you quite likely forgot to test: What if the data that’s expected to be a singular value happens to be an array? If you assumed a GET or POST parameter will never be an array, your site probably joined the ranks of several high-profile sites that go into funny-mode when given unexpected arrays…

How are you submitting arrays when HTTP doesn’t support that?

It’s easy to overlook a simple PHP feature when writing forms or taking parameters in the URL: If you append any parameter name with [], PHP turns it into an array!

Take almost any PHP-based website which uses GET or POST, and modify the parameters into arrays and bang.

Example exploit

Let’s imagine you have a site which has a search feature. As is typical, your site takes the search phrase as a GET parameter like so:

www.mysite.com/search?query=ponies

Very innocent looking parameter there. But what if it was written like this…

www.mysite.com/search?query[]=ponies

Things will go wrong very fast from this point onwards!

The same applies to forms:

<form method="post" action="handler.php">
 <input name="name" />
 <input name="comment" />
 <input value="Send" type="submit" name="send" />
</form>

Quite a normal looking form there. But what if we were to change the code – for example by using Firebug or Opera’s source editor, which both are capable of changing a site’s code on-the-fly

<form method="post" action="handler.php">
 <input name="name[]" />
 <input name="comment[]" />
 <input value="Send" type="submit" name="send" />
</form>

Altering the form ever so slightly suddenly makes the POST parameters get turned into arrays, which may cause subtle problems…

What this “array injection” may cause?

Very typical problem caused by array injection is simply PHP error messages. Another is that your code behaves in slightly erroneous ways, and depending on the case, this may allow someone to abuse your code to do something you never intended it to do.

You’re vulnerable even if you use a framework

The annoying part of this is that unless you check for arrays, you won’t spot this.

Here’s some examples of usually okay parameter processing:

Plain PHP example

$foo = '';
if(!empty($_POST['foo'])) {
  $foo = $_POST['foo'];
}
 
//If you assume here that $foo is a string, you might be in for a surprise...

Zend Framework example

public function myAction() {
  $foo = $this->getParam('foo', '');
 
  //You're still vulnerable!
}

 

The solution

The solution to this issue is simple: Always check data type!

Remember to test your code with array inputs. You might be surprised – I have tested this with a bunch of PHP sites I quickly found, which included some big ones, and almost all of them had a bit weird behavior with this!

This may not sound very dangerous immediately, but better be safe than sorry, no? One possible problem coming from this is that it might be possible to screw up your database queries, possibly making for a Denial of Service attack, or worse.