2

I'm a JS game dev who's been trying to combat tampermonkey scripts for a while now. I came up with a solution for people hooking into WebSockets where I'd cause the WebSocket to throw an error new WebSocket(0); (0 throws an error due to it being a number)

        let output;
        try {
            output = new target(...args);
        } catch(e) {
            let source = e.stack.substring(e.stack.indexOf("("), 1 + e.stack.indexOf(")"));
            e.stack = e.stack.replace(source, "nothing to see here");
            throw e;
        }

this code made the error's stack have all the information I was looking for replaced!

I've been looking at Object.defineProperty, and I was wondering how I could stop an error's stack from being modified before I have access to that specific error. And if anyone has any other ways I could stop a script from being loaded or run, I'd love to hear them!

1 Answers1

0

One thing you could do is Object.freeze the error before throwing it. This would prevent people from altering the object's contents.

So for example:

try {
  new WebSocket(0);
} catch (wsErr) {
  throw Object.freeze(wsErr);
}

The code catching your error and trying to alter it would fail to be able to alter it. This should work as it will cause the code that was altering the error to throw with the following:

Cannot assign to read only property 'stack' of object '' 

The other thing you'll have to consider is that in your code where you're catching the error, you will not be able to alter its contents either. Typically with errors, that's not a huge deal though. Tampering with errors is one of the only reasons I can think of for modifying the error.

Souperman
  • 5,057
  • 1
  • 14
  • 39