1

Say I want to be able to detect if someone calls the following method:

document.querySelectorAll('input');

Is it possible for me to hook this call so that if any other scripts loaded in my context, I can log its execution?

Context: I'm thinking of ways to mitigate Man in the Browser Attacks via a chrome extension, and function hooking is one thing I thought of.

This question neatly demonstrates that I can hook a call for my own uses, but clearly other scripts would have to use MY hooked function, which defeats what I'm after. I'd like to be able to hook document.querySelectorAll() at a level that all other scripts are invisibly using it.

[EDIT] Additional information

Specifically, I'm looking for a way to be able to detect when document.querySelectorAll('input'); gets called, anywhere in my context, period. The context in this case would be a loaded page with multiple scripts imported.

For the record, I'm pretty sure that this can't be done via javascript alone without modifying the interpreter its running on.

Community
  • 1
  • 1
avgvstvs
  • 6,196
  • 6
  • 43
  • 74
  • I strongly suspect that this would require modifying the browser's interpreter, but javascript is such a dynamic beast that well, who knows? – avgvstvs Nov 18 '14 at 16:45
  • So you want to hook `querySelectorAll` for everyone else and use the original `querySelectorAll` your own code? Is that correct? That's what I though you were after, but seems to be opposite of "*...other scripts would have to use MY hooked function, which defeats what I'm after.*" Could you give a step-by-step example case? – apsillers Nov 18 '14 at 17:11
  • What you're asking is not impossible, but I don't see how intercepting every call would guard against MITM...? – Rob W Nov 18 '14 at 18:58
  • 1
    Search for examples of Monkey Patching JavaScript. It's like playing with fire though and I would never do it if I'm writing a library which others will use. If it's just for your site, then you only run the risk of shooting yourself in the foot. – Brian Ledsworth Nov 18 '14 at 19:02
  • @RobW I picked "MiTM" because "MiTB" isn't a tag. It won't stop MiTM (proxy) attacks. What I'm trying to devise is a way to detect MiTB attacks, which usually occur via a `` injected into the web page--like what BeEF does. – avgvstvs Nov 18 '14 at 19:14
  • @avgvstvs I misunderstood what you meant by "*other scripts would have to use MY hooked function*". I see now that you mean "*other scripts would **need to opt-in** to using my hooked function*". I was confused because I thought you meant "*other scripts would **have no choice** but to use my hooked function*" which is actually true (unless they actively `delete` your hooking function). There's only one `document.querySelectorAll` for the whole environment shared by all scripts on the page. – apsillers Nov 20 '14 at 17:02
  • Note that you may be able to overcome the `delete` weakness with `Object.seal` or `Object.freeze` or a non-configurable property with `Object.defineProperty`. I haven't thought it through totally, though. – apsillers Nov 20 '14 at 17:07
  • @apsillers This is why I suck at communication, your initial understanding was correct: I'd like to work through an extension to trap low-level calls--I don't want other scripts on the DOM to be able to escape my calls. – avgvstvs Nov 20 '14 at 18:56

1 Answers1

1

You can override host/native objects just like user-land objects.

var $ = document.querySelectorAll;

document.querySelectorAll = function () {
  console.log('Selecting elements', arguments); 
  return $.apply(document, arguments);
};

Simply putting this snippet in a content script wouldn't work as content scripts run in an isolate scope and any variables set by them are not visible to other scripts. You'll have to append this script to the DOM for other scripts to use the overridden function.

var script = document.createElement('script');
script.textContent = '(' + overriddenFunction ')()';
document.head.appendChild(script);
c.P.u1
  • 16,664
  • 6
  • 46
  • 41
  • 1
    Unfortunately there is no way to do this and guarantee that your hook will be in place before the page begins executing scripts. – Chris_F Dec 21 '16 at 00:55