19

There is a page (game), which communicate via WebSocket to the server. I can see the data (frames) in the Chrome Developer Tool. Is it possible to access / modify this communication from a chrom-extension?

user1930254
  • 1,251
  • 5
  • 17
  • 32

5 Answers5

17

Currently, the only way to access or modify Websocket traffic is to use a content script to inject a script that replaces the WebSocket constructor with your own wrapper. This wrapper should behave like the original WebSocket implementation, but you can add more stuff, like logging the sent/received messages to your extension.

To prevent sites from breaking, you must make sure that your WebSocket wrapper is fully standard-compliant. The interface that has to be implemented is documented at http://www.whatwg.org/specs/web-apps/current-work/multipage/network.html#the-websocket-interface.

For inspiration on how to wrap a DOM constructor, see e.g. my wrapper for Worker. You are free to re-use parts of the code (e.g. the implementation of the EventTarget interface, which is also a requirement of the WebSocket API).

More emphasis: Make sure that your implementation adheres to the interface of the standard WebSocket API, or you could break some sites!

Community
  • 1
  • 1
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • How would that work, considering that content scripts have sandboxed execution environment? It would not replace `WebSockets` used by the page. – Xan Apr 04 '14 at 19:26
  • @Xan Follow the "inject a script" link in my answer. – Rob W Apr 04 '14 at 19:27
  • "My god, it's full of stars!" - thanks for sharing that – Xan Apr 04 '14 at 19:40
  • thank you! I have maneged to inject my script into the DOM. They use dojo-cometd for webSocket communication. My idea to overwrite the org.cometd.WebSocketTransport's onMessage function. The problem: my script.js fires before org.cometd's js loaded-> org is undefined. (although if i use console.log(org) i can see it). – user1930254 Apr 05 '14 at 00:08
  • here is the cometd.js http://pastebin.com/hecAcnus the WebSocketTransport function is in line 565. – user1930254 Apr 05 '14 at 00:12
  • @user1930254 I suggest to replace the WebSocket constructor instead of `WebSocketTransport`, so that you do not depend on the specific of the dojo-cometd library. – Rob W Apr 05 '14 at 08:19
  • i think it should be now possible without your recommandation. Please see here: https://developer.chrome.com/extensions/webRequest, they say: "Starting from Chrome 58, the webRequest API supports intercepting the WebSocket handshake request. Since the handshake is done by means of an HTTP upgrade request, its flow fits into HTTP-oriented webRequest model. Note that the API does not intercept:" Doesn't that mean that we now have acces websocket's traffic via chrome.webrequest api? – Cenk Ten Feb 19 '18 at 00:51
  • @CenkTen go read it again, it does not intercept websocket messages, only the upgrade – spy May 25 '18 at 17:29
9

Seems like the bug is fixed and available. In the manifest.json you need to explicitly specify the permissions

{
  ...
  "permissions": ["webRequest", "ws://*/*", "wss://*/*"]
  ...
}

and in the network filters it should be specified as a websocket request.

const networkFilters = {
    urls: [
        "wss://echo.websocket.org/*"
    ]
};
chrome.webRequest.onBeforeRequest.addListener((details) => {
    const { tabId, requestId } = details;
    // do stuff here
}, networkFilters);
Lenny4
  • 1,215
  • 1
  • 14
  • 33
Jishnu A P
  • 14,202
  • 8
  • 40
  • 50
5

There is a WebSocket-Wrapper, you can use it to access WebSocket traffic:

https://github.com/gorhill/chromium-websocket-wrapper/blob/master/chromium-websocket-wrapper.js

Cenk Ten
  • 283
  • 5
  • 20
2

Judging from discussion on this bug, there is currently no API to intercept WebSocket traffic, unlike normal requests with chrome.webRequest. It's assigned but not completed yet.

Edit: recent (as of Nov 2016) activity on the bug suggests a patch in the works.

Xan
  • 74,770
  • 16
  • 179
  • 206
  • And still no API (6 Years Man), probably they don't want to add it to chrome because the extensions will misuse it too much – Ace Dec 15 '20 at 21:41
-1

I came across this question and tried solutions above, unfortunately the scripts in my target site still found WebSocket has been tampered and broke, which is bad.

So I come up with my own solution:

var ws = window.WebSocket;
window.WebSocket = function(a,b){
var ret = new ws(a,b);
let handle = setInterval(function(){
                  if(ret.onmessage){
                     clearInterval(handle);
                     let o = ret.onmessage;
                     ret.onmessage = function(m){
                                       //do what your want to m
                                       o(m);
                                     };
                   }
                   },50);
                   return ret;
              }

If the site you want to inspect does use WebSocket, I will definitely assign to onmessage sometime after creating WebSocket object, just check it periodically and reassign it with your own function.

Eddie Deng
  • 1,399
  • 1
  • 18
  • 30