On Sun, 02 Jan 2011 18:27:43 +0100, porneL <[email protected]> wrote:

I'm wondering if it's possible to execute code in a bookmarklet in a way that prevents interference from a hostile web page. Specifically I'm interested if a secret value can be hidden in bookmarklet that cannot be intercepted by the page.

It should be possible, depending on what you otherwise do.

...
I've tried that few years ago, but back then browsers executed Array and String constructors for literals. This is fixed now, right?

Pretty certainly. Do you remember which browser and version had this problem?

If this were a bookmarklet, would it keep the secret safe?

(function(){
        try {
                var secret = "secret";
        }
        catch(e){}
})();

That seems completely safe, yes.
(Unless some browser makes the bookmarklet visible in location.href - the one
browser I just tested didn't).

Is there any point fiddling with function's toString?

In this case, no, since the function isn't available to anyone.
In any other case, no, since an attacker can do
 Function.prototype.toString.call(yourFunction).

Can I call untrusted functions without exposing the function in arguments.callee?

No, arguments.callee still exists, sadly. To avoid that, you'll need some
intermediate function to do the calling. But then again, given the next question,
there isn't really any function you would want to call.

How can I ensure that charCodeAt() hasn't been tampered with?

You can't. Running as a bookmarklet, the page has had ample time to cook up
its own environment for you to run in. Any and all built-in functions may have been changed. Including Function.prototype.call, window.eval and window.parseInt.

You can only really use features that have specific syntax (function call,
property access), and not anything that might call an internal function.
And you should be prepared for any object property write to maybe hit a setter.

You can create literals, including Array and Object literals, but you must expect their prototypes to be tainted, including having getter/setter properties (currently some browsers mistakenly trigger these on literal creation, let's hope that gets
fixed soon).
You can create RegExp objects, but you can't trust their methods, so they aren't
really useful.

To hash domain I need to iterate over characters in window.location.hostname.

Some (but possibly not yet all) javascript engines allow you to write "string[index]" to access single characters (it's in ES5), but that still only gives you single character strings. To get a number, you need either to trust charCodeAt (which won't happen), or to use own mapping from single character strings (or some subset that
you care about) to numbers. E.g., a literal like:
 {'a':1,'A':1,'b':2,'B':2, ... long literal! ... '/':87, '.':99}
You probably need both lower and upper case, since you can't trust toUpperCase.

Speaking of window.location.hostname, is it trustworthy? Can someone fake it with getters, prototypes, variable shadowing or any other trick?

I can't guarantee anything for all browsers out there, but it seems that generally neither "global.window" nor "global.location" can be overwritten. Test in more/all
browsers to be certain :).


I like your way of thinking. It's *almost* paranoid enough (knowing that you can't
ever be paranoid *enough*).

/L

--
To view archived discussions from the original JSMentors Mailman list: 
http://www.mail-archive.com/[email protected]/

To search via a non-Google archive, visit here: 
http://www.mail-archive.com/[email protected]/

To unsubscribe from this group, send email to
[email protected]

Reply via email to