The cardinal rule of web development is never trust user supplied data to be safe. A surprising number of developers don’t take this seriously when inserting into a database. An even larger group incorrectly trust their raw data for output. This opens upon the browser to what are called injection attacks.
Usually following these two techniques religiously is enough to secure your application from injection attacks. However, I ran into an interesting problem the other day that requires a third type of escaping.
For example, imagine you have the following php script:
<script> var bug="<?= addslashes( $_GET['urlvar'])?>"; </script>
I could abuse this script to generate the following output:
<script> var bug="</script><script>alert(document.domain)</script>"; <script>
Here is a sample PHP function that does what we need:
So the output with hex codes escapes in the string would be:
<script> var bug="\x3C/script\x3E\x3Cscript\x3Ealert(document.domain)\x3C/script\x3E"; <script>
<div id="mydiv"> </div> <script> var bug="\x3C/script\x3E\x3Cscript\x3Ealert(document.domain)\x3C/script\x3E"; document.getElementById('mydiv').innerHTML=bug; <script>
The script above re-introduces the injection vulnerability because it takes our nice clean string and tells the browser it is html. Before doing that we need to again convert the string into a safe format.
<div id="mydiv"> </div> <script> var bug="\x3C/script\x3E\x3Cscript\x3Ealert(document.domain)\x3C/script\x3E"; document.getElementById('mydiv').innerHTML=html_entities(bug); <script>
However, an alternative technique, which is my prefered technique is actually to use the jQuery and it’s built in jQuery.text() method which tells the browser to inject plain text rather than html.
<div id="mydiv"> </div> <script> var bug="\x3C/script\x3E\x3Cscript\x3Ealert(document.domain)\x3C/script\x3E"; $('#mydiv').text(bug); <script>
Any time you are sending data between layers you need to examine the format of the data that the source is expecting and translate your data as appropriate. The following table summarizes the built-in php functions you can use to prepare your data for use.
|Destination||PHP function to encode with|
On a related note, if you are passing user supplied data on the command line, don’t! In Linux there is no way to escape the single quote character, so the best you can do is remove single quotes. Instead find a way to pipe your data into your program rather than using the command line. It’s must safer and will allow you to work with single quotes. If you insist on passing command line variables see php’s escapeshellarg() function.