Escape Input and Output

There is a surprising amount of confusion about XSS and SQL injection among the PHP programmers I’ve worked with. Here are some common ways to do it right and to do it wrong.

Escaping Input (protecting against SQL Injection):

  • NO: add slashes or run mysql_real_escape_string() on everything in the REQUEST before using.
  • YES: strip unexpected characters and validate data. If you need a phone number, don’t allow all types of symbols, for example.
  • YES: use SQL binding before inserting database data. PDO offers some nice binding. All PHP frameworks offer systems that automatically bind data. At the least, use mysql_real_escape_string() or the correct one for your database engine.

Escaping Output (protecting against XSS):

  • NO: run strip_tags() on the way in. strip_tags() is not meant for scrubbing input can let in malicious HTML. In fact, using string_tags() is probably never what you need.
  • NO: run html_entities() before anything comes into the database. What if you need to write database data to a printed check? You don’t want to accidently print “O'Connor” on someone’s check.
  • YES: use an HTML parser with whitelisting on any data coming in from a WYSIWYG (e.g. HTMLPurifier).
  • YES: cast numbers to integers or floats.
  • YES: use view helper functions to format dates, dollars and other data.
  • YES: run html_entities() on all text, even if you “know” it is safe. The view is autonomous and should assume all input has not yet been escaped.
  • YES: Get familiar with research and OWASP recommendations.