Watching some asshat fail at cross site script...

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.

  1. Never pass data from untrusted origins into output without either escaping or sanitising it.
  2. Never forget to validate data arriving from an untrusted origin using relevant rules for the context it’s used in.
  3. Remember that anything not explicitly defined in source code has an untrusted origin.
  4. Remember that htmlentities() is incompatible with XML, including HTML5′s XML serialisation – use htmlspecialchars().
  5. Always include ENT_QUOTES, ENT_SUBSTITUTE and a valid character encoding when calling htmlspecialchars().
  6. Never use htmlspecialchars() as the primary means of escaping Javascript, CSS or URL parts.
  7. Never use json_encode() to escape Javascript strings unless using PHP 5.3 and RTFM.
  8. Use rawurlencode() to escape strings being inserted into URLs and then HTML escape the entire URL.
  9. 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”).
  10. Validate all complete URLs if constructed from untrusted data.
  11. Never validate URLs using filter_var(). It doesn’t work and allows Javascript and Data URIs through.
  12. Never include resources loaded over unsecured HTTP on a page loaded over HTTPS.
  13. Sanitise raw HTML from untrusted origins using HTMLPurifier before injecting it into ouput.
  14. Sanitise the output of Markdown, BBCode and other HTML replacements using HTMLPurifier before injecting it into output.
  15. Remember that HTMLPurifier is the only HTML sanitiser worth using.
  16. Adopt the Content Security Policy (CSP) header and abandon the use of inline CSS and Javascript where feasible.
  17. Always transmit, with content, a valid Content-Type header referencing a valid character encoding.
  18. Ensure that cookies for use solely by the server are marked HttpOnly.
  19. Ensure that cookies which must only be transmitted over HTTPS are marked Secure.
  20. 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.

Enhanced by Zemanta

Related posts:

  1. Automatic Output Escaping In PHP And The Real Future Of Preventing Cross-Site Scripting (XSS)
  2. CodeIgniter 2.0.2: Cross-Site Scripting (XSS) Fixes And Recommendations
  3. A Hitchhiker’s Guide to Cross-Site Scripting (XSS) in PHP (Part 1): How Not To Use Htmlspecialchars() For Output Escaping
  4. PHP Escaper RFC: Consistent Escaping Functionality For Killing XSS
  5. Open Letter to Gareth Heyes: Regex HTML Sanitisation Doesn’t Work