Chrome extension API for intercepting/modifying websockets UA
Asked Answered
N

4

5

I'm trying to write an extension that will modify the User-Agent on all outgoing requests from Chrome.

For http://, https://, ftp://, file://, or chrome-extension:// I can use the chrome.webRequest API and onBeforeSendHeaders. However, this does not work for ws:// or wss://.

Is there some other API that allows me to set/modify headers on these requests?

Neural answered 8/5, 2015 at 12:28 Comment(0)
B
8

I was googling for an answer to this question, and since it now, three years later, is possible, I'll document it here.

According to https://developer.chrome.com/extensions/webRequest, it should work from Chrome 58. But there were several configurations required in order to make it work.

  • In the manifest permissions must be requested for webRequest and webRequestBlocking
  • Permissions must also be requested for the web socket URLs, like "wss://*/" and "ws://*/"
  • In the request filters (in the addListener function calls) the urls must be declared with wss or ws scheme. Using * as scheme resolves as http and https only
  • In the request filters, websocket has to be declared in types. (I'm not sure if this is required, I don't have time to verify that)

And remember, webRequest is only available in background scripts, and not in content scripts.

Example (changing the Origin header, changing User Agent should be similar)

In manifest.json:

"permissions": [
"storage",
"tabs",
"activeTab",
"webRequest",
"webRequestBlocking",
"webNavigation",
"debugger",
"https://*/",
"wss://*/"
],

In the background script

// origin is defined somewhere above
chrome.webRequest.onBeforeSendHeaders.addListener((details) => {
      if (origin) {
        const headers = details.requestHeaders;
        for (let i = 0; i < headers.length; i++) {
          if (headers[i].name === 'Origin') {
            headers[i].value = origin;
          }
        }
        return { requestHeaders: headers };
      }
    }, { urls: ['wss://server.example.com/*', 'https://server.example.com/*'],
         types: ['xmlhttprequest', 'websocket'] },
       ['requestHeaders', 'blocking']);
Barogram answered 18/5, 2018 at 8:31 Comment(2)
It's not worked to me. My chrome don't intercept websocket request (Carpous
sending wss from background script does not work. but sending wss from chrome-extension://extension-id/some-page works.Greatcoat
U
3

I'm afraid not. Now possible for the request headers, see this answer.

That would be a nice feature request though.

Unintentional answered 8/5, 2015 at 12:42 Comment(1)
Link to feature request. For those interested.Neural
B
1

in case someone's using new declarativeNetRequest api and wants to block websocket, you need to mention url with wss:// protocol ex: urlFilter: "wss://augloop.office.com"

chrome.declarativeNetRequest.updateDynamicRules(
  {
    addRules: [
      {
        action: {
          type: "block",
        },
        condition: {
          urlFilter: 'wss://augloop.office.com/', //block this websocket
          domains: ["example.com"], // on this domain
        },
        id: 2,
        priority: 1,
      },
    ],
  },
  () => {
    console.log("block rule added");
  }
);

Boyce answered 15/5, 2022 at 11:57 Comment(0)
E
0

For Manifest Version 3: You need to declare WebSocket in host permissions

"host_permissions": ["*://*/*", "wss://*/*"],
Edora answered 2/10 at 20:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.