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]