13

So, here is the issue.

I have something like:

// Dangerous __hostObject that makes requests bypassing 
// the same-origin policy exposed from other code.
(function(){
    var danger = __hostObject;
})();
delete __hostOBject;

Am I perfectly safe knowing no script can tamper or access __hostObject?

( If they can, I have an CSRF vulnerability or worse. )

Note 1: This is for a browser extension. I have better hooks than other scripts running on the page. I execute before them and I'm done before they've even loaded.

Note 2: I know this has been asked multiple times for scripts in general. I'm wondering if it's possible if I know I load before any other scripts.

Community
  • 1
  • 1
Benjamin Gruenbaum
  • 246,787
  • 79
  • 474
  • 476
  • I've written a [sample code](http://jsfiddle.net/35G8e/2/) which overwrites `Function.prototype.call`. (Feel free to flag this post if you really think that I am helping malicious devs. In my opinion, the eventual attackers will know these techniques anyway.) – ComFreek Dec 15 '13 at 11:48
  • 1
    @ComFreek You've forgot to `return` the result of `oldCall`. But indeed, that's the general principle used to monkey-patch (built-in) JavaScript methods. – Rob W Dec 15 '13 at 11:55

2 Answers2

5

Provided that the __hostObject is deletable, the code in your question is safe.

However, I assume that your real code is slightly more complicated. In that case, very careful coding is required, because the page can change built-in methods (e.g. Function.prototype.call) to get into your closure and do whatever evil things they want. I had successfully abused functionality of extension frameworks such as Kango and Crossrider via this method when I performed such a test.

Rob W
  • 315,396
  • 71
  • 752
  • 644
  • You're very sharp today (or lucky but I'd like to think sharp). This is a problem we're having with Crossrider right now. I'm now testing a BHO for internet explorer and I need to let JavaScript make requests that bypass the cross origin policy and/or store cross site data in the registry. Both very problematic operations. I couldn't think of a better way. (Also, if you could add example code for such an exploit with `.call` - that'd be really swell). Is there a reliable way to kill the app if something like `.call` was tampered with? (In afterthought - they can do it _after I load too). – Benjamin Gruenbaum Dec 15 '13 at 11:40
  • 1
    @BenjaminGruenbaum The code to abuse the functionality is trivial, I will not post sample code to avoid feeding malicious devs. I'm just writing an answer to your other question, stay tuned ;) – Rob W Dec 15 '13 at 11:42
  • I am sorry guys. I am trying to understand the problem and the solution, but couldnt. Can you guys please explain a bit more? – thefourtheye Dec 15 '13 at 11:44
  • @thefourtheye which problem and which solution? Please elaborate exactly on which part you did not understand. – Benjamin Gruenbaum Dec 15 '13 at 11:45
  • @BenjaminGruenbaum First, your question. I don't get the actual problem :( – thefourtheye Dec 15 '13 at 11:46
  • @thefourtheye I have a function that is exposed from an extension (it's not written in JavaScript) but I need to execute it in JavaScript since that's what the cross-browser extension is developed in. While browsers like chrome and firefox provide execution sandboxes, IE does not (as far as I know) meaning I need to execute unsafe JS code. What I was wondering was whether or not putting the dangerous code in a closure and deleting any outside reference is enough to prevent it from being touched from the outside (like in the question code). – Benjamin Gruenbaum Dec 15 '13 at 11:48
  • @BenjaminGruenbaum Wouldn't you just need to save every reference to any, outside the closure available , Function you're calling within your code and use that instead, like calls made to bind, apply, array constructor etc.. – Moritz Roessler Dec 15 '13 at 12:19
  • @C5H8NNaO4 to _every single function_ that is exposed globally? Also, I'd have to write all my function code wrapped. – Benjamin Gruenbaum Dec 15 '13 at 12:29
  • @BenjaminGruenbaum To every function that is exposed globally, which you call in your code and where you pass references to objects where it would be unsafe if any member could be accessed or reassigned. The only way i can think of to use the original reference to call is however assigning the original reference temporarily directly to the function being called, from within a custom call function. Heres a simple [fiddle](http://jsfiddle.net/Glutamat/j9N6t/) – Moritz Roessler Dec 15 '13 at 13:30
  • @C5H8NNaO4 I provided `Function.prototype.call` merely as an example. What about `var data = __hostObject.getSensitiveData();if(data.split(';')[0] == something) { ... }`? Wrapping all possible inherit calls is very cumbersome and errorprone. Think of the fun you'll have with patching third-party libraries in this way? – Rob W Dec 15 '13 at 13:36
  • @RobW Sure. *(Oh, forget the previous rev, just saw `String.prototype.split`)* But what other ways are there besides wrapping the calls, where references are being passed, which shouldn't leak to the user? Either you would have to make sure the references, leaking, wouldn't grant the user more power over the page he originally had, or you have to make sure the reference is not leaking, or do i miss something? – Moritz Roessler Dec 15 '13 at 13:55
  • @C5H8NNaO4 Explanation of my comment: Say, you're using a third-party JavaScript library such as jQuery. Now, you want to make sure that you're not accidentally leaking access to your privileged API. How are you going to wrap all calls in [jquery.min.js](http://code.jquery.com/jquery.min.js) without breaking the library, missing a call or wasting much time? I do not know of any way to solve the problem without sacrifying at least one of the previously mentioned points. If you wish to discuss this topic further, feel free to create a chat at http://chat.stackoverflow.com/ and invite me. – Rob W Dec 15 '13 at 14:03
  • @RobW Thanks for the explanation :) that makes perfect sense, so theres actually no way as long as you're in the same execution context as the page – Moritz Roessler Dec 15 '13 at 14:18
0

Won't simply adding a breakpoint and reloading the script expose your __hostObject

Verneri Åberg
  • 390
  • 1
  • 9