最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Hooking Websockets from a Chrome Extension - Stack Overflow

programmeradmin1浏览0评论

I'm trying to create a Chrome extension content script which can hook the WebSocket of a specific page. Currently when the page is accessed, the content script injects another script into the page like so:

    var s = document.createElement('script');
    s.src = chrome.extension.getURL('Script.js');
    s.onload = function () {
        this.remove();
    };
    (document.head || document.documentElement).appendChild(s);

Then my Script.js contains an addEventListener for the websockets.

Window.WebSocket.addEventListener("message",function(event){
console.log("Websocket read");
})

But when I run the extension I receive an error can not read property addEventListener of undefined. So I'm not entirely certain if that's the correct way to do it. I have verified that the script does get injected the page but how would I override or create my own listener on top of original onmessage WebSocket from the page. Is it possible?

I'm trying to create a Chrome extension content script which can hook the WebSocket of a specific page. Currently when the page is accessed, the content script injects another script into the page like so:

    var s = document.createElement('script');
    s.src = chrome.extension.getURL('Script.js');
    s.onload = function () {
        this.remove();
    };
    (document.head || document.documentElement).appendChild(s);

Then my Script.js contains an addEventListener for the websockets.

Window.WebSocket.addEventListener("message",function(event){
console.log("Websocket read");
})

But when I run the extension I receive an error can not read property addEventListener of undefined. So I'm not entirely certain if that's the correct way to do it. I have verified that the script does get injected the page but how would I override or create my own listener on top of original onmessage WebSocket from the page. Is it possible?

Share Improve this question edited Nov 27, 2021 at 21:01 Ahmed Hany 1,0407 silver badges14 bronze badges asked Oct 4, 2018 at 15:32 TofuTofu 3,6132 gold badges13 silver badges37 bronze badges 15
  • can you try with lower caps window like window.WebSocket.addEventListener? – Arun Kumar Commented Oct 4, 2018 at 15:35
  • Hello, when I change it to window.WebSocket.addEventListener I receive this error: Uncaught TypeError: window.WebSocket.addEventListener is not a function – Tofu Commented Oct 4, 2018 at 15:38
  • use onmessage instead like window.WebSocket.onmessage = function(event) { console.debug("WebSocket message received:", event); }; – Arun Kumar Commented Oct 4, 2018 at 15:41
  • 1 where did you deifined Window.WebSocket ? I'm not expert of chrome extension but I think it is wrong. In javascript you should first create an instance of websocket using new keyword. – pouyan Commented Nov 27, 2021 at 10:38
  • 1 Does this answer your question? stackoverflow./questions/22868897/… – skara9 Commented Nov 28, 2021 at 20:42
 |  Show 10 more ments

3 Answers 3

Reset to default 3 +200

WebSocket is a class. The addEventListener function is only available in an instance of the class. So you must find the variable the web page creates and add the listener to that. For example:

var mySocket = new WebSocket("wss://127.0.0.1:8080");

You would do something like:

mySocket.addEventListener("message", (e) => console.log(e));

However, this will miss all the initial messages and it depends on you being able to get access to the variable which may not be possible in all situations.

Instead, what you can do is override the class with your own class so that when they create a WebSocket instance, its actually your class.

An example of that would be something like:

class MyWebSocket extends WebSocket
{
    __constructor()
    {
        super(...arguments);
    }

    addEventListener(name, callback)
    {
        // call the original event listener
        super.addEventListener(name, function()
        {
            console.log("Im sneakily listening in here", arguments);

            // call their callback
            callback(...arguments);
        });
    }
}

// Override the real web socket with your version
window.WebSocket = MyWebSocket;

Keep in mind the above code is pseudo and untested.

If you just want to see the socket data. You can open chrome dev tools, click the "ws" filter. Then click on the web socket listed and view the raw data being transferred.

Here is a working sample that should work from your context script.

while(document == null || document.head == null);

var s = document.createElement("script");

function hookWebSocket()
{
    window.RealWebSocket = window.WebSocket;

    window.WebSocket = function()
    {
        var socket = new window.RealWebSocket(...arguments);

        socket.addEventListener("message", (e) =>
        {
            console.log("The message is: ", e);
        });

        return socket;
    }
}

s.innerHTML = `
    ${hookWebSocket.toString()}

    hookWebSocket();
`;

document.head.prepend(s);

You can use wshook which overrides the original WebSocket class and add callbacks which can be used for the task

You can directly copy the script wsHookjs and paste before your code or import like normal javascript and then start using it.

Import the library

<script src='wsHook.js'></script>

then you can just add callbacks for either before or after or both to intercept websocket send request:

wsHook.before = function(data, url, wsObject) {
    console.log("Sending message to " + url + " : " + data);
}

// Make sure your program calls `wsClient.onmessage` event handler somewhere.
wsHook.after = function(messageEvent, url, wsObject) {
    console.log("Received message from " + url + " : " + messageEvent.data);
    return messageEvent;
}

Note: Content Script can be loaded before page load. For more information about how to load content script before page load you can check this post

Could you try with this?

s.onload = function () {
  this.parentNode.removeChild(this);
};
发布评论

评论列表(0)

  1. 暂无评论