PHP Security: Sanitizing Strings, Validating Values, and Interrogating Integers

php_security_201009.jpgTrust no-one. Not just a tag-line for The X-Files, it’s also sound advice when dealing with data supplied by users.

Whether a user is trying to do something nasty or they’ve just hit an unfortunate combination of keys, you shouldn’t assume that what you’re saving is trouble-free. Here are some tips for validating input in your PHP application.

Numbers Only

Zend Framework has a handy class called Zend_Filter_Int that will take a value and strip out any non-numeric characters. Or, you could do something like this:

$output = preg_replace("/[^0-9-.]/", "", $data);

This will allow negative numbers and decimal points.

Strip Tags, Display Tags

Don’t want any HTML? Use strip_tags. If you’d prefer to display HTML tags so a user can share a code snippet, use htmlspecialchars and the code won’t be parsed.

Escaping Strings in MySQL

Use mysql_real_escape_string to escape strings before sending them to MySQL. Or, use PDO and bind values to fields.

Use filter_input

Instead of using $_GET['id'], how about using filter_input instead?

$itemId = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_SPECIAL_CHARS);


What other methods do you use for sanitizing user input?

Is Your PHP Application Affected by the Y2K38 Bug?

I don’t want to be too alarmist, but try running the following PHP code on your system:

$date = ’2040-02-01′;
$format = ’l d F Y H:i’;
$mydate1 = strtotime($date);
echo ’<p>’, date($format, $mydate1), ’</p>’;

With luck, you’ll see “Wednesday 1 February 2040 00:00″ displayed in your browser. If you’re seeing a date in the late 60’s or early 70’s, your PHP application may be at risk from the Y2K38 bug!

What’s the Y2K38 bug?

Y2K38, or the Unix Millennium Bug, affects PHP and many other languages and systems which use a signed 32-bit integer to represent dates as the number of seconds since 00:00:00 UTC on 1 January 1970. The furthest date which can be stored is 03:14:07 UTC on 19 January 2038. Beyond that, the left-most bit is set and the integer becomes a negative decimal number — or a time prior to the epoch.

Yes, it’s 28 years away and I’m sure many of you think it’s ridiculous to worry about it now. However, developers thought that way about the Millennium bug the 1970’s and 80’s. Also, any web application which handles long-term future events could be at risk. For example, a typical mortgage runs for 25 years. Pensions and savings plans can be far longer.

Will 64-bit save us?

Probably. If you’re using a 64-bit OS with a compiled 64-bit edition of PHP, your application shouldn’t be affected. I’d recommend you test it, though. A signed 64-bit number gives a maximum future date which is 21 times greater than the current age of the universe — 292 billion years, give or take a day or two.

You can probably sleep at night if you’re convinced your financial application will always be installed on a 64-bit system.

Are there alternative options?

Fortunately, PHP introduced a new DateTime class in version 5.2 (experimental support was available in 5.1 and be aware that some methods were introduced in 5.3)

$date = ’2040-02-01′;
$format = ‘l j F Y H:i’;
$mydate2 = new DateTime($date);
echo ‘<p>’, $mydate2->format($format), ‘</p>’;

DateTime does not suffer from Y2K38 problems and will happily handle dates up to December 31, 9999. I might have paid off my mortgage by then!

It may not be worth upgrading existing applications, but you should certainly consider the DateTime class when planning your next project.

PHPIDS Secure your php app.

PHPIDS (PHP-Intrusion Detection System) is a simple to use, well structured, fast and state-of-the-art security layer for your PHP based web application. The IDS neither strips, sanitizes nor filters any malicious input, it simply recognizes when an attacker tries to break your site and reacts in exactly the way you want it to. Based on a set of approved and heavily tested filter rules any attack is given a numerical impact rating which makes it easy to decide what kind of action should follow the hacking attempt. This could range from simple logging to sending out an emergency mail to the development team, displaying a warning message for the attacker or even ending the user’s session.