7

Definitions: Please note from the outset that by 'injected script', 'extension code' and 'content script' I will be using the definitions provided in the excellent first answer to this question.

Assumption: Handling confidential information is less secure if I do it directly within my injected script (in the web zone) than if I do it within the chrome:// zone of content scripts and extension code. I therefore should use message passing to send confidential information from the web zone to the chrome:// zone for it to be handled.

Question: I'm building a Google Chrome extension where I need to run some operations on sensitive user data derived from my injected script. The data in question is confidential and I must do all I can to ensure that it can't be seen by anyone but the user of the extension until I've operated on it. Of the 3 techniques (defined below) that can be used to pass messages between an injected script and extension code/content script which would be best for this purpose?

My understanding of the 3 different techniques that can be used for passing data between an injected script and extension code/content script:

  1. For messaging passing between an injected script and extension code (e.g. a background page), one can use the chrome.runtime API.

  2. For messaging passing between an injected script and a content script one can use window.postMessage.

  3. Another way of passing messages between an injected script and a content script is via document.dispatchEvent(CustomEvent).

My understanding is that method 1. cannot be used for message passing between an injected script and a content script while methods 2. and 3. cannot be used for message passing between an injected script and extension code (unless the message is forwarded by the content script to, for example, a background page).

Community
  • 1
  • 1
user5508297
  • 805
  • 2
  • 9
  • 24
  • 1
    First technique is (in my opinion) the best option to use since anyone can intercept messages from `window.postMessage` (assuming the domain matches) and `document.dispatchEvent` if they know they're going to happen. At least you can restrict the first technique to broadcast to specific extensions only by passing an extension id. – Patrick Roberts Jul 11 '16 at 14:14
  • Another 4th option you haven't mentioned is creating a `XMLHttpRequest` with CORS to a secure website and relaying that information from the server back to the extension via a socket or long polling. – Patrick Roberts Jul 11 '16 at 14:16

1 Answers1

6

While code running in your background page / content script is pretty well isolated, as soon as you inject a script into the page context - you're in the Wild West. Any extension, and the page itself, has access to that context and can influence how your code executes.

For example, some extension can override chrome.runtime.sendMessage to send the message AND log it. This needs to be seriously taken into account - probably, you already lost.

That said, method 1 is harder to break into than 2/3 - as explained, the attacker extension would need to directly alter the page context to interfere, while in case of DOM events it can just listen to them from the safety of its content script - events are broadcast to all content script contexts.

Hypothetically, you could employ some sort of asymmetric cryptography for the channel as well - provide the injected script with the encryption key and keep the decryption key in the privileged zone. That safeguards the communication, if that's the only thing intercepted, but at some point the plaintext data exists in the global context - that may be enough for the attacker script to extract (that, you have to assume, executed before your injected script).

Xan
  • 74,770
  • 16
  • 179
  • 206
  • Thanks for your reply @Xan. Would it be fair to say that the security of method 1 therefore relies on these 2 assumptions? 1.) That the webpage I'm injecting my code into won't try to intercept the message passing and 2.) That I can trust my user to protect themselves from attackers gaining access to their computer and surreptitiously installing a malicious extension that intercepts the message passing. – user5508297 Jul 11 '16 at 16:26
  • I forgot another assumption: 3.) That the webpage I'm injecting my code into is not vulnerable to the usual web security flaws that an attacker could exploit to inject their malicious script into the webpage. – user5508297 Jul 11 '16 at 16:42
  • 1
    I would advise against adding crypto because it may add a false sense of security. It is better to focus on developing trustworthy primitives that you know to *not* be compromised. That is, inject your script at `document_start` and save a copy of a callable `dispatchEvent` / `postMessage` or (possibly better than the previous because it is non-global) `MessageChannel`. @user5508297 But since you're assuming that the web page is not compromised ("assumption 3"), I don't see what you're trying to mitigate. – Rob W Jul 12 '16 at 09:13
  • @RobW I tried to say that it's futile to add crypto, kind of what-if situation. I didn't do a good enough job, perhaps. – Xan Jul 12 '16 at 09:14
  • 1
    @RobW And injecting at `document_start` is not a panacea, since the attacker may happen to be injected at `document_start` earlier in eligible extension list. You can NEVER assume you drew your gun first. – Xan Jul 12 '16 at 09:15
  • @user5508297 I don't understand your threat model. You're basically saying "assuming the website is not malicious, secure, and the browser environment is secure". Then what's the potential threat? – Xan Jul 12 '16 at 09:19
  • @Xan, oh no that's not my threat model. I was just flipping the question around and asking under what conditions it would be considered completely safe to pass confidential information using method 1. The assumptions I listed in the comments above are, of course, unrealistic. – user5508297 Jul 13 '16 at 09:39
  • Then the minimal assumption is "website code and your injected script is the only code executed in that page context". Unfortunately, any extension can circumvent that. – Xan Jul 13 '16 at 09:49
  • True. Thanks again for all your help @Xan (extending also to everyone else who commented on my question). – user5508297 Jul 14 '16 at 15:42
  • Hi everyone, I've got a new question about secure message passing in Google Chrome extensions - do any of you have an answer? Any help would be highly appreciated. http://stackoverflow.com/questions/38579382/google-chrome-extension-message-passing-can-any-useful-checks-be-performed-on-t?noredirect=1#comment64547919_38579382 – user5508297 Jul 26 '16 at 16:39