Tuesday, April 27, 2010

Clickjacking and (i)frame-based attacks, and how to fight them.

The web is so choke full of malicious sites, that I have become extremely paranoid. If I suspect even a hint of malicious code on a site I am visiting (such as unwanted popups), I rush to the Alt-F4 key close it and consciously avoid any mouseovers/mouseclicks. If that does not work, I will kill the browser session from the task manager. Firefox has an annoying habit of trying to reload the same site after a crash-recovery. You can change that behavior from going into the about:config and changing the browser.sessionstore.resume_from_crash setting to false.

Clickjacking is one way the baddies can hijack your clicks or keystrokes by craftily positioning their own content obscure/hide legitimate content you are browsing, and deceive the user into clicking on hidden element. So when you click or type, it gets passed on to the hidden layer beneath which could be the hijacker's form to capture personal information.

The root of this attack is the bad guy placing your web page in a frame or iframe. He can now manipulate the layers and what is visible to the user since he controls the top level or outer frame.

The classic way to prevent your content from being framed is to put a "frame-buster" javascript at the top of your page:
<script>if (top!=self) top.location.href=self.location.href</script>

Unfortunately, the bad guys can defeat this method in a number of ways:

1. The attacker can interrogate the onbeforeunload event and redirect the top.location and have their own server respond with a 204. The Wikipedia framekiller article describes this technique so I won't go into the details.
2. Override the location.href setter (__definesetter__) in webkit family of browsers. Therefore even if your frame busting script runs, the location.href will not do the job.
3. IE has SECURITY="RESTRICTED" option which can allow the attacker to turn off scripting in the inner frame (where they will put your content, and obviously the frame busting script will not run)

OK, so how do we combat these "anti-busting" techniques? The best way I have worked out is implementing any one or both of these methods:

(a) This will thwart the first anti-busting attack, but will fail with 2 and 3.

<script>if(top!=self){var s=self.location;setInterval(function(){top.location.replace(s);s=null},1)}</script>

(b). Style the <body> to hide content. Then later unhide with scripting after verifying you are not framed. That way even if the attacker thwarts your frame busting efforts, your content is hidden (as well as the clickjacking content) until you successfully bust out of the frame.

<body style="visibility:hidden"><script>if(top==self)document.body.style.visibility='visible'</script>

This method(b) doesn't really stop the attack, But hides the content of the page when framed, so a blank page is displayed, therefore the intent of the attacker is defeated! The downside here is that it will show blank page when scripting is turned off, or security(zone) setting is high. This should not be too much of a concern, as in today's world Javascript is so ubiquitous, that turning off scripting will virtually render virtually every site crippled.

UPDATE(June 9, 2010): Another solution: All major browsers (latest releases) except FF now support the "X-FRAME-OPTIONS" meta tag. Check out Eric law's post. However, since Firefox does not support it as well as all older browsers (IE 6,7 etc),this is not a very effective solution - instead I would use the above (a) and (b) anti-busting countermeasures.

Sunday, April 4, 2010

ASP.net MVC 2.0 Attribute-based Validations using metadata

I have been meaning to publish this for a while. This is a terrific shortcut to quickly create the metadata scaffolding from the Data Access Layer (DAL) created from LINQ2SQL. You will need to download and install Expresso, and be a little familiar with the tool, as well as it will help if you know a bit about regular expressions.

1. Regenerate DAL (I recommend you use SQLMetal).
2. Copy required tables from designer.cs into Expresso regex editor (Test Mode) "test area"
3. Simple find "public (?!e|E|.*\().*" (without the quotes). Then Run Match
(this gets rid of all junk except class name and properties)
4. Take the Match Results and copy-to-clipboard, them paste back into the "sample text" area (REPLACING the existing text from step 2).

5. Now we do a regex find/replace in Expresso.
Go into Design Mode:
Search String: "public (?!partial)[^ ]+ (.+)"
Replace String: (copy the entire string without the quotes, but include the carriage return at the end)
"public object $1 { get; set; }
"
Back to Test Mode and click "Replace"

6. Copy the replaced-text area back into the sample-text (same as step 4)

7. Finally decorate the class and add braces:
Go into Design Mode:
Search String: "public partial class (\w+).*"
Replace String: (copy and paste the entire block below exactly as shown, without the quotes, and including the carriage return at the end.
"}
[Bind(Exclude = "Id")]
[MetadataType(typeof($1MetaData))]
public partial class $1{}
public class $1MetaData
{
"
Back to Test Mode and click "Replace"

8. That's it! copy the final text into a new visual studio "metadata.cs" in the models. You have nice clean scaffolding to add your validation attributes. The [Bind] attribute is a placeholder.