Within the world of application development, there is a conspiracy.
What’s wrong with this code? The problem is that
$username needs to be escaped before it can be put into the SQL statement. If
$username contains single quotes, the SQL statement will do something you did not intend. If you already know this, stick around, there’s more to this story.
Without escaping the data before it is added to the SQL, the code is vulnerable to Injection attack. Injection is the top security risk in applications, according to OWASP’s Top 10 Security Risks>.
Here’s the corrected code:
See the really long function name
mysql_real_escape_string()? The long length is part of a conspiracy to discourage you from escaping injected data.
If you work much with SQL, you may also know about parameterized SQL statements, which automatically escape the injected data, and they reduce the need to concatenate bits of SQL together.
Let’s pull out the essential parts from the PHP example. The
$username value is data. It’s being injected into the source code of a computer language called SQL. Notice these three keywords:
Look for these words as we move on.
Here’s another example:
The situation is the same as before, but now the language is HTML. We’re still injecting some data,
$username, into the language. And like the first SQL example,
$username is not escaped.
The security attack that leverages this defect is called Cross-Site Scripting (XSS). XSS is the number two security risk, according to OWASP’s Top Ten list. XSS is actually just another case of Injection. The defect that causes these two vulnerabilities is the same kind of defect– failing to escape data that is being injected into a language.
What does PHP provide you to avert certain disaster?
1 2 3
In case you weren’t thinking of it already, I just want to say, PHP is one ugly language.
With a name like
htmlspecialchars(), you might guess it was not intended to be used often. Actually, nine out of ten times it is perfectly appropriate to use
htmlspecialchars(). If the length of
htmlspecialchars() bothers you as much as it does me, I suggest writing your own shortcut:
1 2 3 4 5 6
Only when you really want to inject actual HTML would you not use
htmlspecialchars(). And when you do so, be sure the HTML is either trusted or sanitized.
Do you see the pattern? The language is HTML, the data is
message for injecting it into HTML? Nothing. Absolutely nothing. What does jQuery give us for the task?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Now “message” can be escaped:
So there you have it: three examples of injection, and three solutions for escaping data before injecting it into language code.
Using a templating language that escapes by default is great, and so is using parameterized SQL statements. But don’t think that you don’t have to worry about escaping data again. If you work with multiple languages, you will eventually need to call upon an escape function.