PHP, Zend Framework and Other Crazy Stuff
Archive for April, 2013
20 Point List For Preventing Cross-Site Scripting In PHP
Apr 22nd

Watching some asshat fail at cross site scripting attacks against gearfuse.com. (Photo credit: vissago)
Summarising knowledge has as much value as writing a 200 page treatise on a topic, so here is a list of 20 brief points you should bear in mind when battling Cross-Site Scripting (XSS) in PHP. Minus my usual book length brain fart . Chances are good that ignoring or acting contrary to any one of these will lead to a potential XSS vulnerability. It’s not necessarily a complete list - if you think something needs to be added, let everyone know in the comments.
- Never pass data from untrusted origins into output without either escaping or sanitising it.
- Never forget to validate data arriving from an untrusted origin using relevant rules for the context it’s used in.
- Remember that anything not explicitly defined in source code has an untrusted origin.
- Remember that htmlentities() is incompatible with XML, including HTML5′s XML serialisation - use htmlspecialchars().
- Always include ENT_QUOTES, ENT_SUBSTITUTE and a valid character encoding when calling htmlspecialchars().
- Never use htmlspecialchars() as the primary means of escaping Javascript, CSS or URL parts.
- Never use json_encode() to escape Javascript strings unless using PHP 5.3 and RTFM.
- Use rawurlencode() to escape strings being inserted into URLs and then HTML escape the entire URL.
- Never ever pass escaped or sanitised data from untrusted origins into a Javascript execution context: a string later executed as Javascript, e.g. setAttribute(“onclick”, “PLEASEGODNOTHERE”).
- Validate all complete URLs if constructed from untrusted data.
- Never validate URLs using filter_var(). It doesn’t work and allows Javascript and Data URIs through.
- Never include resources loaded over unsecured HTTP on a page loaded over HTTPS.
- Sanitise raw HTML from untrusted origins using HTMLPurifier before injecting it into ouput.
- Sanitise the output of Markdown, BBCode and other HTML replacements using HTMLPurifier before injecting it into output.
- Remember that HTMLPurifier is the only HTML sanitiser worth using.
- Adopt the Content Security Policy (CSP) header and abandon the use of inline CSS and Javascript where feasible.
- Always transmit, with content, a valid Content-Type header referencing a valid character encoding.
- Ensure that cookies for use solely by the server are marked HttpOnly.
- Ensure that cookies which must only be transmitted over HTTPS are marked Secure.
- Always review dependencies and other third party code for potential XSS vulnerabilities and vectors.
Cross-Site Scripting remains, by far, the most common vulnerability in web applications. Things that will sink your application, framework or library become very obvious from the list. There are more than enough naughty applications, frameworks and libraries around that you should have little trouble identifying offenders with grep and some mental acrobatics. Rumour has it that you can now locally search any project on Github without even cloning a repository.
Yes, some entries are reminders. It’s surprising how many people try to avoid HTMLPurifier in favour of the month’s Regular Expression Powered Miracle option which is riddled with holes or have formulated the belief that, contrary to its official syntax rules, Markdown magically prevents Cross-Site Scripting.
Mockery 0.8.0 Has Been Unleashed!
Apr 2nd
I’m very happy to announce the release of Mockery 0.8.0.
Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succint API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit’s phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.
The new version of Mockery is the first in a year (since 0.7.2) and is packed with new features, bug fixes and even better support for PHP’s OOP model. It’s also the first version to be released with my new co-conspirator, Dave Marshall (@davedevelopment), who threatens to make me redundant as a maintainer! This version focuses primarily on stability but it’s worth reviewing the README for the new sections on Creating Partial Mocks and Behaviour Modifiers for mock objects.
For those who haven’t been using dev-master in their composer.json project file, you can now update to the 0.8.0 stable tag using Composer or grab the 0.8.0 package from the PEAR channel at http://pear.survivethedeepend.com.
A very special thanks to those who opened pull requests and reported issues over the past year.