Using HTML5 postMessage For a Secured Cross Domain Communication and Rendering

In the previous post, we covered how easy it is to build an environment where anyone can write in HTML, CSS, JS code that gets rendered and displayed in a sandbox (iframe) in realtime. It’s all good as long as the platform is restricted to yourself, but when it becomes open, i.e., when others can create testcases or use it for some other purpose as on CSSDeck, you need to start thinking about security.

Problems

Let me first cover some of the problems with our current approach where we simply manipulate the contents of the iframe.

Access To The Parent Window

The main (or top or parent or whatever you want to call it) window object is accessible from inside the iframe:

window.top
// or
window.parent
// maybe some more ways!

That piece of code is enough to access the parent window, using which one can do anything on it. For example injecting scripts, audios, videos, manipulating the DOM in any way, redirecting to another site via the location object, etc.

Now, if Mr. Hacker creates an item with some nasty Javascript code that does one or more of the aforementioned actions, it could hurt anyone who tries to access it. Danger for users!

Same Origin Attacks

Mr. Hacker writes a piece of code that makes an API call to a URL on the same origin to possibly fetch Username, User Email, User ID, etc. and then submits some random form (again on the same origin) with those details. Lots of spam for you and your users. Oh! and he has your user’s precious email now.

If you don’t know what same and different origins mean, then read this article on MDN.

Solution

The solution is to have the iframe on a different origin. For example, <iframe src="http://subdomain.yoursite.com"></iframe>. But now, how do we achieve realtime rendering with the iframe being on a different origin ?

HTML5 postMessage to the Rescue

HTML5 comes with a new API – postMessage that is well supported by all major browsers. Even IE8 and up supports it, but only for frames and iframes, NOT other tabs or windows. We are dealing with iframes anyway.

This allows us to safely communicate with an iframe on a different origin. I am not going to explain it in details as MDN does a very good job at that.

Now all you have to do is, send the source (JSON.stringify it if required) to the iframe using iframe_node.contentWindow.postMessage(). In the iframe you receive the data, check origin (for security) and perform the same operations we covered in the previous post, which is: 1. Using document.open, document.write and document.close or 2. Creating and Injecting style and script nodes (with a body node for HTML if required or set the innerHTML property of the document.body).

Notes

Hey, I want to tell you something. You should be a good ethical person! If you ever find security issues on any site related to anything, you should try NOT to harm them, but instead inform them about the vulnerabilities. This way you can not only help them out, but also help the community they have built around. Maybe the patches they develop to fix the issues will get released back into the community, which means more and more people are going to benefit and we’re going to have access to better softwares and services.

Isn’t that awesome ? You earn more karmas!

Coming Up

Wouldn’t it be nice if we had a really nice text editor over plain textarea elements that supported syntax highlighting, indentation and lots of other cool stuffs to enhance our coding experience. Exactly what we’ll cover in the next part.

Share:

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>