Snippets Of Defense Pt.I

Sun, 07 Oct 2007 12:17:48 GMT

This article is the start of a series of posts about small and easy to understand code fragments you can use on your site for protection against certain kinds of attacks. Also this series is targeted to help you understand better what tricks are used by attackers to break your site and how to avert this. If you have a Snippet of defense yourself and want to share it feel free to contact us.

The first snippet - overwrite alert() wit a logger

The JavaScript method alert() is mostly used for debugging purposes and very rarely found in live applications. Attackers though very often use this method for initial probing for XSS vulnerabilities on websites and web applications. Most PoCs found in forums and newsgroups make use of this method and meanwhile you can even find tons of links including alert()-based PoCs via Google.

So combining those facts puts up the question why not overwrite the alert() method with a method that logs the request - which probably was fired by an attacker. First, we know that the attacker managed to inject JavaScript on our page because the modified alert() method has been executed. And second you logger script will tell you all you need to know about the malicious request. So here we go - place this code in between script tags inside your application's header or add it inside your application's JavaScript files:

var old_alert = alert;
alert = function(a) {
    var img = new Image();
    img.src = 'http://the/uri/to/your/logger/file';
    img.style.height = 0;
    img.style.width = 0;
    document.body.appendChild(img);
    old_alert(a);    
    return false;
}

Till the next time.

KishorKishor
Nice trick to get your app scanned for xss for free! Although, a frustrated attacker could add dummy entries to your logs. And since you believe that the log file contains accurate XSSs , you may have hard time removing those false entries. You may need something more at server side to detect such spamming.
asciiascii
hi mario! a simple bypass is
alert=old_alert;alert("test");
but i know you didn't intended this as a silver bullet, more like a kiddie protection. wisec has published some info on how to block the fetch/set of a cookie value for geko based browsers, it's more generic than trap alert() http://www.wisec.it/sectou.php?id=44c7949f6de03 it can be bypassed too using frames and other techniques (eg: you can try everything but if it's hooked in js it can also be reverted to the original in js). anyway why not? it's cheap! i'm going to implement both on my sities ps: pdp make this textbox larger please : )
clinisbutclinisbut
Yeah it's a good way to detect when someone try to hack our site. But there is the famous Firebug extension for firefox that offers the console.log() to debug apps. Maybe a function like yours would be necessary for firebug? ps:I know my english is poor...
RoC_MMRoC_MM
pdp, this is a good blog, I read it all the time. ascii, in cases like this, I use the "enlarge textareas" bookmarklet. Make a bookmark with this as the URL, then click it anytime you are on a page with a too small text box.
javascript:(function(){var i,x; for(i=0;x=document.getElementsByTagName(%22textarea%22)[i];++i) x.cols += 150; })()
asciiascii
@RoC_MM: thanks good bookmarklet!
kuza55kuza55
Personally I don't like this for two reasons: a) It places IDS logic into the web page, thereby giving it to the attacker b) It puts you in a position where an attacker can easily clog your IDS with false positives c) It won't work if referers are turned off Sure, in regards to (b), you could collect more data, but you still need some way to verify it - you might be able to automate this by getting some machine to visit the pages in the referer (or passed to your logged as a GET parameter), but that's just ugly (and seems like a wide open security hole), and it also tells you nothing about POST XSS's, and so unless you want to discount all the POST XSS's this detects, you would have to investigate every referer you get with no parameters (or parameters for which your page uses POST data). So while it might work, it will probably give people a false sense of security, and be a headache to administer if anyone malicious notices it.
djtellerdjteller
Kuza55, this is against kiddies, and since 99% are using automated scripts that will work just fine. You can even obfuscate this code to make it harder to read. Always good to have logs, even if they are false you can learn from them.
bedirhanbedirhan
Sorry if this makes a duplicate post, but during the last one your domain seemed to go down :(. If we can change the code to;
alert = (function(){
    var old_alert = alert;
    return function(m){
        // logging goes here
        old_alert(m);
    }
})();
then by-passing would be a little harder. This is creating private members thru closures.
pdppdp
bedirhan, excellent. I did something similar for technika. I needed to insert some code, but I did not wanted to pollute the this namespace with some random vars such as i or anything along these lines. My solution is the following:
(new function () {
  return function (self) {
    // your code here
  };
})(this);
This is almost like self executing, self destructive code. sweet!