PhpRiot
News Archive
PhpRiot Newsletter
Your Email Address:

More information

Mistrust and Verify

Note: This article was originally published at Planet PHP on 24 December 2010.
Planet PHP

When working on a web app with coworkers or fellow volunteers, few things are more important within the group than trust. Trust among developers enables them to work confidently, eases communication between team members, and empowers each of them to make good decisions.

With the actual app, however, that trust should never come easily. With today's web apps, you can't trust anything. You can't trust input from the user, you can't trust your code, you can't trust your processes, and you can't trust your systems. So, while the Russian proverb says, aoD"DDDuNND, DD DNDDDuNND,a meaning, aotrust and verify,a these days you need to mistrust and verify.

The user

A user doesn't need to be malicious to break your app, but malicious users do exist, so no input from any user can trusted. Any data received is immediately suspect, needs to be validated that it is the expected format (numbers are numbers, dates are dates, postal codes are valid, email addresses match RFC 822, and required data is the right length) and filtered to remove dangerous input. Plenty of articles exist on how to avoid SQL injection, but preventing cross-site scripting attacks and session hijacking is also important.

You should mistrust data coming into your app enough to read the articles in the PHP Security Consortium library, follow a post a day for a month of PHP security, or spend an hour reviewing the basics of PHP security.

A great resource (and must-read) for beginnersa-athat is full of great reminders for experienced developersa-ais Essential PHP Security, which succinctly lists problem areas where all PHP developers should be cautious, along with solutions.

Fortunately for developers who prefer using frameworks, most PHP frameworks will handle the data checking and filtering, preventing common security holes. If you use a framework, embrace its way of handling data so as not to thwart its processes. Mistrust it just enough to verify it does what you expect, then sign up for its security mailing list. When a fix is reported, download the patch and review the changes; have you made the same error in your code?

The code

Input from users is only one part of the app; your code is another How do you trust your code, which, while brilliant at two in the morning, is perhaps less brilliant the next morning? You don't. You write unit tests.

Unit tests let you automate the tedious job of verifying that your code works correctly and is returning the right data formats. They let you know when changes adversely affect the rest of the system.

SimpleTest and PHPUnit are two popular PHP testing frameworks. Creation of unit tests have been made relatively painless, but not error-free nor effortless.

After your unit tests are written, testing all of your functions and libraries, can you really trust them? Not really. Unit tests are white box testing; you know what your code is (supposed to be) doing, you know what input is going into the test, and you know what you're expecting to be returned. With all of this knowledge, no, you can't even trust your unit tests, as each step is known, but input from users is an unknown.

To be effective, unit tests need to be complete and need to be updated to handle the new cases you see during development and in production. Each time a bug is found, a problem discovered, or an exploit exposed, a unit test should be created for the issue. Brainstorm on edge cases; you might not put control characters in your form input fields, but people who cut and paste, or maybe use Emacs, just might. For multilingual applications, have you tried to break your tests with other languages?

A review of your unit tests from time to time is also a good idea. Ever look at a completed part of your project and find this?

/** * Test validName function * @param string input name * @return boolean */ function testValidName($name) { // TODO: write validName test return true; }

The deployment

So, user input

Truncated by Planet PHP, read more at the original (another 5447 bytes)