Validate your inputs

Todays podcast listening for the commute was Bruce Sams talking about web app security from Software Engineering Radio.

Starting with a live demo of some hacking techniques (surprisingly effective even with just the audio), it covers some of the popular attacks – SQL injection, javascript in input fields, cookie stealing, guessing adjacent ID numbers and so on.

Apparently about 70% of web app vulnerabilities come from the inputs to the system – we spend a lot of time worrying about things like SSL and encrypted logins, but actually the vast majority of attacks use the applications themselves.

Sams says that when he’s asked for his top 10 tips for making your web app secure, he says:

  1. Validate your inputs properly
  2. See (1).

An interesting aspect of validation, though, is that it applies not just the obvious things like form fields and text strings, but to all the HTTP header elements as well.

For example, WordPress MU (in versions prior to 2.7) had a function that would echo the HTTP Host header without having sanitised it. The attacker can craft a request that contains some Javascript in the Host header which, when echoed, can grab cookies (or other evil cross-site scripting stuff)..

Resetting the oil service light on a 2006 BMW 320i

The oil service warning light on the BMW was still on after the last oil service, so I looked around for how to reset it. Lots of advice on the internet, but mainly involving special tools (aka paperclips) and dodgy shorting-out of pins in the diagnostic port.

There’s also talk of holding down the trip reset button whilst turning the ignition key to the first position, then releasing and pressing and holding the button again. But there IS no ignition key in the recent BMWs..

The answer turned out to be a bit more easily guessed (after a bit of trial and error). When you start the engine, the oil service warning shows on the dashboard, at which point you just press the BC button on the end of the indicator stalk (which is how you access most of the diagnostics anyway). The word “reset” appears, and another click and hold on the BC button makes it show “resetting” (and a little clock icon so you know it’s busy). And that’s it.

Put away the paperclip.

PhpUnit Mocks that suddenly stopped working

We came across a strange thing with the mock framework in PhpUnit .

We had some test code that created a mock for a Store class, and gave it a method to mock out:

        $mockStore = $this->getMock(‘Store’, array(‘save’));

That seemed to work fine in the tests, we could setup expectations, the correct return values got returned, and so on.

Then, in some unrelated code, we changed some require_once statements, and suddenly the test with the mocks stopped working – it threw exceptions trying to create the Store mock. 

It turns out that the constructor for the Store class needed some parameters, and the mock framework needs you to supply those parameters when you create the mock, because it will call the real constructor behind the scenes.

The mock had been working OK previously because the real Store class hadn’t been loaded anywhere by the test – but then the changes to some require_once statements elsewhere in the code meant that the Store class WAS now loaded, and instantiated by the call to create a mock.

 

So the mock framework in PhpUnit will create a mock for you even if it has no idea what class it is that you’re trying to mock out – you could do

        $mockStore = $this->getMock(‘foo’, array(‘save’));

and it would still give you a mock that worked fine. If it DOES find a class of that name, though, it’ll instantiate it.

In fact, this behaviour is probably a good thing for TDD – it means you can create the mocks you need before you’ve ever created the real classes. You just have to be aware that when you DO create the real class, the mocks will start being created based on the real thing.

 

The solution in our test was to use the flag that tells the mock framework not to call the original constructor – it’s a bit more clumsy, because you also have to supply some other additional parameters:

        $mockStore = $this->getMock(‘Store’, array(‘save’), array(), ”, FALSE);