Nov 10 2012

NULL Hyderabad Meet-November 2012

Category: security | techNovoGeek @ 16:44

It has been a nice honor to organize NULL Hyderabad Chapter's monthly meet for November 2012 (EventBrite site). The event had good turnaround (imagine ~50 tickets being sold online in about 1.5 hours) and had good speakers.

The first speaker Bipin Upadhyay gave a fantastic overview of HTTP protocol, discussed about RFCs and gave an interactive presentation. He compared the output of WireShark and explained how OSI model can be simplified and taught in colleges. That was fun! The second speaker Srinu gave a good presentation on Malware analysis, covering Stuxnet, Flame, Guass and Duqu. 

Below are the slides shared by the speakers on SlideShare:

The meet was fun with several IT security enthusiasts interacting, sharing their knowledge and expertise. NULL meet takes place every month and you need not be an IT security expert to attend. If you are in IT field, you are very much qualified to attend. Register at http://null.co.in/ for future events.

Tags: ,

Sep 30 2012

What you know about AJAX, is not the same in HTML5 CORS

Category: Web 2.0 NovoGeek @ 04:53

“AJAX is for asynchronous calls within same origin whereas HTML5 CORS is for asynchronous calls across origins”. This is a popular comparison of AJAX vs CORS which many web developers do, but there is a lot beyond this!

Improving website performance by replacing full page postbacks with AJAX is something which web developers frequently do. By definition, in an AJAX call, an asynchronous XMLHttpRequest will be fired to a target URL using JavaScript. One obvious thing which should not happen is a cross origin call from a browser to a different origin (i.e., an advertisement on a web page should not be able to make a call to gmail.com). This restriction is set by browsers in the form of a policy called Same Origin Policy (SOP), which we are well aware of (related post: JSONP is not cross origin AJAX).

The boundary restriction set by SOP prevents security breaches at one end but limits the scope of interaction of websites at the other end. Wouldn't it be nice if you can mash up data from different servers (origins) on a single webpage using JavaScript without hacks like JSONP? Or block someone else's calendar with POST AJAX request using JavaScript? It is for this reason that HTML5 has a new policy (a complete specification) which allows cross origin calls to happen and it is called CORS (Cross Origin Resource Sharing). In short, CORS works based on access policies set in special response headers. i.e., in order to allow cross origin calls, the server should declare a whitelist of zero or more origins to which it will give access like:

    Access-Control-Allow-Origin: http://localhost

Similar to the above response header, there are a bunch of response headers which help browsers in checking various access permissions. If you are new to CORS, I suggest you to visit HTML5 rocks, which has a detailed tutorial. In this post, I would like to focus on browser security checks.

Browser security checks – AJAX vs CORS:

Let us say you are using a browser which does not support HTML5 CORS and your application is hosted at http://localhost:81. If you open http://localhost and try to make an AJAX call to your app, you will get this security error message:

"Access to restricted URI denied" (message text varies across browsers, essentially conveying SOP violation).

var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:81/handler.ashx", true);
var params = 'name=AJAX';
xhr.setRequestHeader("Content-Type", 'application/x-www-form-urlencoded');
xhr.send(params);

Browsers do this Same Origin Policy check even before they trigger a network call.

Now if you install a browser which supports CORS and try the same (without configuring any response headers), you will get the message:

XMLHttpRequest cannot load http://localhost:81/. Origin http://localhost is not allowed by Access-Control-Allow-Origin”.

The message clearly conveys that the check happened after making a call to the remote server. This is obvious, since CORS is based on response headers and browsers do not have any clue whether the remote server allowed the call or not without checking the response. In this context, browser developer tools sort of confuse developers by saying that “the request is cancelled”. In reality, browsers “do the request but just do not render the response in case CORS headers are not found. To test this, you can simply log the call on your server and you will have log entries.

<%@ WebHandler Language="VB" Class="Handler" %>

Imports System
Imports System.Web
Imports System.IO

Public Class Handler : Implements IHttpHandler

Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim str As String = context.Request.Params("name")

Dim sw As StreamWriter
Dim strDate As String
strDate = context.Timestamp

sw = New StreamWriter(context.Server.MapPath("logs.txt"), True)
sw.WriteLine(strDate + " : " + str)

sw.Flush()
sw.Close()

context.Response.ContentType = "text/plain"
context.Response.Write("Hello " + str)

End Sub

Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property

End Class

The above code is the content of my remote .ashx handler hosted on http://localhost:81 (okay, I’ve written the above code in VB but who cares! As long as you understand what it does, language doesn’t matter. My next demos will be using Java Servlets/PHP..yes, I’m coding in these recently..yay!)

So web developers who have used AJAX and are moving towards HTML5 should know this subtle but important difference.

Cross origin form submission now AJAXified in CORS!

Not sure if you have observed or not, the first code snippet in this post uses a content-type “application/x-www-form-urlencoded”. If you haven’t figured it out, there is a more familiar version of it which you already know:

<form method="post" action="http://localhost:81/handler.ashx">
<input type="text" name="name" value="fake form">
<input type="submit" value="Submit">
</form>

When HTML forms are submitted, they use “application/x-www-form-urlencoded” as the default content type. Since forms anyways do cross origin posts inherently, this “feature” was also included in HTML5 CORS specifications. This is the reason why we were able to log the CORS message in the second snippet. So all the three content types which are supported by HTML forms (“application/x-www-form-urlencoded”, multipart/form-data”, “text/plain”) can be used in CORS to do a cross origin request (Don't you smell attack scenarios here? Stealth mode attacks? Yeah!)

No preflight request for CORS POST request?

The HTTP methods GET and HEAD are called “safe methods” since they should not cause any state changes on the server. POST requests are meant to change the state on the server and can be misused. So there should have been a preflight request for the above CORS POST request, but browsers did not do such thing in the above demo.

The reason for this boils down to what is allowed vs not allowed prior to HTML5 specs. In HTML4, we could do cross origin requests using <img src=’…’>, <script src=’…’>, <form method=”GET/POST” action=’…’> etc. Following the same rules, cross origin GET requests and some POST requests can still be done using CORS. So what are those “some” POST requests? These are nothing but what we have seen above in the form submission case. i.e., POST requests with various form content-types. Other than these, any sort of POST request will require a preflight request, which is the security enhancement in CORS.

HTML Forms and CSRF attacks go hand in hand. What about CORS & CSRF?

Yes, CSRF attacks using HTML forms are quite popular and one of the well known defenses is sending random, unique nonce in every request. Since CORS POST requests mimic HTML form requests, they can be victims of CSRF attacks and hence every CORS POST request should use CSRF defenses. If this is not considered seriously, it paves way to a number of stealth attacks such as silent file uploads. In the first snippet, if you set “xhr.withCredentials=true”, even cookies can be sent in the POST requests and hence replay attacks can be done.

Winding up the show, CORS is beautiful and enhances the modern web interactions in many ways. We already know how bad the state of AJAX security has been, owing to poorly written code. If CORS is studied as ‘yet another new thing on the web’, without understanding the internal details, web applications will suffer big time leading to serious attacks. Time to focus on the security aspects of modern web specifications! No escape!!

UpdateYou may check the source code of the demo used in the article here: https://github.com/novogeek/AJAX-vs-CORS

Happy coding Smile

Tags: , ,

Jun 26 2012

HTML5 Sandbox and some notes

Category: security | Web 2.0 NovoGeek @ 08:06

While building mashups, one of the primary goals is to securely isolate content coming from different origins. Generally, client side mashups are built in one of the two ways-(1) Embedding third party scripts in a web page (2) Loading remote content via iframes. Embedding scripts provides more interactivity but dilutes security since the scripts run with full privileges and could be malicious. Using iframes reduces interactivity but enhances security since they isolate content via same-origin-policy (Script inside a cross-origin iframe cannot access DOM of parent page).

[Note: By chance if you are wondering why you should bother about mashups since you have never built them, you are mistaken. If you are embedding scripts for website analytics, social plugins (Like, Tweet, +1 etc.), advertisements, comments system (e.g., Disqus) and so on, you are already having a mashup!]

Though iframes follow same-origin-policy and provide security in some sense, they are well known for their notorious activities like frame phishing, top window redirection, clickjacking, triggering drive by downloads etc. The “sandbox” attribute for iframes which is introduced in HTML5 promises to thwart the problems caused by iframes. Sandbox is currently supported only in Internet Explorer 10, Chrome 17+.

A sandboxed iframe by default disables script, popups, form submissions, top navigation etc. Some of the restrictions can be relaxed by specifying space separated white list tokens (allow-forms, allow-scripts, allow-same-origin, allow-top-navigation).

<iframe sandbox src="http://crossOrigin.com"></iframe>
<iframe sandbox="allow-forms allow-scripts allow-same-origin allow-top-navigation"
src="page2.html"></iframe>


The details about sandbox and its white list tokens are discussed in several blogs, hence purposefully omitting it here. One interesting feature in sandbox is, when a sandboxed iframe loads content from the same origin as the parent document, the loaded content is still treated as if it originated from cross origin, thereby reducing its script privileges. This restriction can be removed by using the token “allow-same-origin”.

Below are some of the cases where developers have to be cautious while using sandbox.

Disabling Clickjacking Defense:

Even till date, several sites rely on JavaScript based frame busting defense to get rid of clickjacking (X-Frame-Options response header is a better defense, but unfortunately has lesser implementation). Such sites when embedded in a sandboxed iframe are greatly affected. Since sandbox disables JavaScript, the clickjacking protection used in the framed site is lost, hence back to square one!

Allow-scripts and Allow-same-origin combination:

This combination of tokens is a little tricky and could negate the effect  of sandbox. The “allow-scripts” token enables JavaScript inside iframe and the “allow-same-origin” token will give the iframe complete privileges to access DOM of the parent. So if the embedded iframe has a vulnerable input field, script can be injected to remove the “sandbox” attribute altogether and then carry further exploits. Thus the security benefits of sandbox can be removed completely.

Effect on Nested Browsing Contexts:

If a webpage has nested browsing contexts (page containing an iframe which in turn loads another iframe), then reasoning about the effect of sandbox tokens becomes complicated. Let us consider the scenario in the image on the right below-a parent page has an iframe to a page (Child1) with "allow-scripts" sandbox token. Child1 loads another iframe which points to Child2 having "allow-forms" token. At a quick glance, developers may conclude that the innermost page will have both forms and scripts allowed, but it is on the contrary. The inner page has everything disabled and for a good reason! The child1 frame has forms disabled and it will overwrite the "allow-forms" of Child2. Also, Child1 has scripts enabled but Child2 has them disabled. Hence it does not allow script execution. So it is advisable not to manipulate sandbox tokens dynamically, since it is difficult to reason about the after effects on sandbox restrictions.

DEMOS: Click the images for demos (Source at: https://github.com/novogeek/html5sandbox )

Sandbox demo 1

Sandbox demo 2

 

 

 

 

 

 

 

 

 

In the first demo, there is an iframe with JS based clickjacking protection and by default sandbox option is selected. You can see the clickjacking defense by selecting “normal frame”. So this shows how sandbox defeats JS based clickjacking defense. Also in the same demo you can select “allow-scripts” and “allow-same-origin” optons and inject the snippets provided below the page into the XSS vulnerable page.

In the second demo, inspect the iframes and load them independently in different windows and to see the effect of sandbox tokens in nested browsing contexts.

Hope the article provided some useful information about HTML5 Iframe Sandbox and its secure usage. Feel free to get back with queries or please share aspects which you feel interesting about Sandbox. Happy coding Smile

Tags: , ,