Why to be concerned about Browser Extensions?

I don’t care about the tech stuff skip to the safety recommendations.

Imagine you have an online kitchen store

flowchart LR classDef vulnerable fill:#f1ac56 classDef critical fill:#ffcccb classDef safe fill:#daf7a6 classDef resetColor fill:#ffffff subgraph Browser direction LR subgraph ActiveTab[Active Tab] websiteJS[kitchen_store.js] contentJS1[content.js] subgraph iframe[fa:fa-lock iframe] paymentJS[payment.js] contentJS[content.js] end end subgraph ExtensionBackend[Extension Backend] backendJS[malicious_backend.js] end end subgraph paymentSite[Payment Site] end class Browser,ActiveTab,iframe,ExtensionBackend resetColor class backendJS,contentJS,contentJS1 critical class paymentSite,paymentJS,websiteJS safe contentJS --> backendJS contentJS1 --> backendJS paymentJS -- https --> paymentSite linkStyle 0 stroke-dasharray: 5 5,stroke:red linkStyle 1 stroke-dasharray: 5 5,stroke:red

In this store, you have some JavaScript for all your kitchen-y stuff, like spatulas and stuff. For anything that’s risky, like handling credit-cards for customer payments you use a 3rd party like Adyen, PayPal or Stripe. To do this, they recommend putting it in an inline frame (iframe) and this also allows you to wrap that content in a content security policy (CSP).

You would add the CSP mostly to ensure that even if there’s some scary code that can get into that iframe, it can only send data to the payment site’s hostname, so any credit card numbers that a customer puts in there are safe from being sent to the wrong place.

Ok, so what’s bad?

  1. While a website (your kitchen store) can control where the iframe can send data, by design Browser Extensions are EXEMPT from this policy!! "I do what I want"
  2. The extension’s content scripts can be loaded into any and all frames in the browser with simple bit of seemingly-innocuous config:
    {
     ...
     "all_frames": true,
     ...
    }
    
  3. Through the combination of content-scripts being injected into all frames (above) and the concept of a background script (or now in Manifest-V3 service worker) security controls such as Same-Origin-Policy (SOP) do not apply to any of the extension’s JavaScript code.
    This control usually helps protect from malicious script in a parent frame “DOM walking” into the child frame. A malicious extension may simply use the well-defined communication mechanism to exfiltrate any data a given content.js scope has access to out to malicious_backend.js, and that background worker is then free to exfiltrate data from the browser to a domain of the attacker’s choosing :(

    N.B. if extension content.js scripts in two different frames need to communicate/coordinate with each other they can simply proxy through the malicious_backend.js.

What do I do to protect myself?

Browser Users

Don’t use browser extensions. The only one you actually need is an adblocker, to achieve this without a Browser Extension here’s the recommendations (either would suffice):

Website Owners

Be aware that you can’t do anything to protect your customers from this threat. If they start reporting anomalous thefts and blaming you, at least add this discussion to your support troubleshooting list.

Btw you can’t enumerate the list of browser-extensions present for privacy reasons, I can attest after having exhaustively tried.

Browser Developers

Figure out a solution? I made some suggestions here that weren’t well received:

Time to use those brains and come up with a genius solution to this mess for consumers.

Some recent improvements

No, the problem is still here, a malicious browser extension can still steal any of your data, regardless of what the website does to help protect you. But there’s been a few changes that at least make the maliciousness more gauche and (theoretically) detectable by the AppStores. That being said, the 2018 announcement to ban obfuscation doesn’t seem to have made any difference, I flagged an app the other day using jscrambler the other day.

In Manifest V3 some safety changes have landed, such as not allowing remote script to execute in an extension!! I didn’t actually know that was allowed in V2… how was that ever thought to be a good idea from Chrome/Firefox store review perspective?!

Background Scripts are now replaced with Service Workers; however, no changes to where content scripts can be injected or adherence to CSP.