1

I'm sending the code of a javascript function that is defined in the parent document:

var fn = function(){ 
           // code here that is going to be eval'd
         };

$('#iframe').get(0).contentWindow.postMessage(encodeURI(fn.toString()));

to be evaluated in the iframe:

$(window).bind('message', function(e){
  eval('(' + decodeURI(e.originalEvent.data) + ')();');
}); 

The reason I'm doing this is because I can manage the code easier, because this way all the js is in one file :)

But is it safe?

The only one who can modify the code is the same person on which's computer the code gets evaluated, right?

Alex
  • 66,732
  • 177
  • 439
  • 641

5 Answers5

4

Apart from the general rule that eval should be avoided if possible, your current code is not secure.

Cross-document messaging is supposed to be a safe technique for cross-origin communication. The most important aspect here is respecting the origins: The sender can decide to which documents of which origin a message may be sent and a receiver can decide of which origins it may accept messages from.

But in your case your sender neither specify the recipient origin nor does the recipient check the sender origin. This is a security weakness as either your sender can send messages to a wrong recipient (your frame’s document changes) or your recipient accepts messages with potential malicious code from a wrong sender (your document is embedded in a malicious page).

So to make your cross-document messaging secure, always specify the sender’s origin within the postMessage call:

otherWindow.postMessage(message, "http://example.org:8080");

And always check the origin when receiving a message:

function receiveMessage(event) {  
    if (event.origin !== "http://example.org:8080") return;
    // ...
}
window.addEventListener("message", receiveMessage, false);

If you’re communicating within the same origin, you can use window.location.origin:

// sender
otherWindow.postMessage(message, window.location.origin);

// recipient
if (event.origin !== window.location.origin) return;

As window.location.origin seems to be available in WebKit only, here’s a workaround:

if (!window.location.hasOwnProperty("origin")) {
    window.location.origin = window.location.protocol + "//" + window.location.host;
}
Community
  • 1
  • 1
Gumbo
  • 643,351
  • 109
  • 780
  • 844
2

Regarding "safe", you're talking about a window, which is technically under complete control of the user (if the user is savvy enough), communicating with another such window or iframe. So basically it's all under the user's control. It's as safe as anything else on the client, which is to say, nothing is safe on the client; it's the wild west out there. You can't protect the user from himself/herself if the user doesn't want to be protected.

That being said, generally there are better ways to get things done that eval(). Almost always.

Jonathan M
  • 17,145
  • 9
  • 58
  • 91
1

How safe is it to eval()?

not safe at all.

Why is using the JavaScript eval function a bad idea?

Community
  • 1
  • 1
Colin D
  • 5,641
  • 1
  • 23
  • 35
0

No, it will be easy to manipulate the code to be executed and other stuff, plus eval is not a good way to get things working

Wanderson Silva
  • 1,179
  • 1
  • 17
  • 35
0

Using the eval() function means if any attacker was to inject javascript into your site, he could execute ANY kind of rogue code within the eval function.

arijeet
  • 1,858
  • 18
  • 26
  • 4
    If he is able to inject JavaScript, he can already do whatever he wants. – Gumbo Jun 22 '12 at 18:56
  • A client user can hack himself all day. That doesn't make your app unsafe. A javascript client app is *always* at the mercy of the client user. – Jonathan M Jun 22 '12 at 19:08