Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to "sandbox" arbitrary JavaScript to only operate on one <div> and not the whole document?

what I am trying to do is to force some arbitrary JavaScript code to execute "inside" a DOM element, e.g. <div>. In other words, is it possible to make a piece of code "thinking" that <div> is the root of document hierarchy (or <body> of a document)?

Real life example:

Let's say we have a page that allows executing JavaScript code:

<!DOCTYPE html>
<html>
<head>
  <title>Executor</title>
  <script type="text/javascript" src="jquery.js"></script>
</head>
<body>
  <div></div>
  <input/>
  <button onclick="$('div').html(eval($('input').val()))">
    Execute
  </button>
</body>
</html>

The code has access to entire document and can modify it, e.g:

$("input").hide()

Will prevent me from writing any stupid code any more ;-)

Is is possible to restrict the area of effect for some piece of JavaScript code? and how to do it if it is possible?

Best regards.

Edit:

The code I want to execute might be everything. If Your solution is based on some kind of modification of the given code, please describe how to do it the right way.

Edit2:

First of all, I do not know why I get a down-vote.

Secondly, the code I will execute is someone else's arbitrary code, not mine.

To make everything clear:

What I am really trying to do is to simulate a browser somehow. Get the content of some web page, and insert in into mine. This is relatively easy when we decided to turn off JavaScript and cut out all places where it might appear, but this is something I cannot do. For now I want to limit only the DOM modification (the malicious code). I will work on redirects and cookies later, when I have a base idea.

like image 263
Dawid Avatar asked Jul 23 '10 16:07

Dawid


2 Answers

The best way to achieve complete isolation and encapsulation of a chunk of code is to put it into an iframe, and put it on a subdomain of your site so that the domain name of the outer HTML page is not identical to the inner HTML page. Inside the iframe, the JavaScript will see only the DOM of the iframe URL and will have no access to the outer DOM. This isolation is enforced by the browser security model.

The plus side to this technique is that you can have high confidence that the script running inside the iframe will not leak out and steal data from your outer page. This isolation is also the downside - it's harder to share data between the outer page and inner page. To provide controlled access or sharing of data between the iframe and the outer page, there are a variety of cross-domain data sharing techniques you could investigate. If you only need to throw arguments "at" the iframe inner page, you could pass the data on the URL as query params. If you need two-way data exchange, you could use domain-lowering techniques to bring the domain names in line briefly so that the browser will allow data exchange between the outer and inner pages.

Since you are proposing to eval() arbitrary code entered in an input control, you definitely should shield your main page logic from potential hackery. Use an iframe.

like image 172
dthorpe Avatar answered Nov 06 '22 12:11

dthorpe


One approach could be encapsulating all of the code that is need to be secured, with an anonymous function, and pass all environmental parameters with similar objects but modified not to allow global DOM manipulations, for simplest example

(function(document,JQuery,$,window){ //make sure all global access methods are here

//eval code here or just copy and paste

})(modifiedDocument,modifiedJQuery,modifiedJQuery,modifiedWindow);

Now the question may come into one's mind, how we can modify the document object? One aproach maybe

var modifiedDocument = function(){

    this.getElementById = function(id){ //one of global accessing functions

         //check if given id is withing the restriction div
         return document.getElementById(id);

         //if found element is not withing restriction div just return null or what is default
         return null;
    }

}

Self-invoking anonymous functions allow us to prevent global variable collisions, and it is used in many well known libraries like jQuery.

To be able to apply this method, first you have to determine every possible way, how a script tries to read or write a global DOM object. I cannot give you complete solution because using this method it is apparently a project may consume my entire week, but this may light your way!

like image 43
Kemal Dağ Avatar answered Nov 06 '22 11:11

Kemal Dağ