How to surreptitiously modify a function in Javascript

Viewed 96

I'm trying to modify a function:

console.error = function() {
  return "fake";
}

However, it is possible to detect the function was changed by just running toString() on it:

> console.error.toString()
'function() {\nreturn "fake";\n}'

If the function hadn't been modified, 'function () { [native code] }' would be returned instead.

A solution can be to override toString(), however, it is possible to see that toString has been overriden by running toString on it:

> console.error.toString = () => 'function () { [native code] }';
> console.error.toString()
'function () { [native code] }'
> console.error.toString.toString()
"() => 'function () { [ native code ] }'"

Is there anyway to recursively override toString() or any other method such that it is not possible to detect the function was overriden?

The use case would be for a WebExtension to modify some functions while making it as hard as possible for a website to detect it.

2 Answers

You can overwrite Function.prototype.toString itself. However, it might still be possible for other code to circumvent this - easiest by taking a reference to the method before you've overwritten it, rather intricate by restoring a version from a different realm.

{
    const Console = console.constructor;
    const origToString = Function.prototype.toString;
    const origError = Console.prototype.error;
    const {error} = {error() { return "fake"; }};
    const {toString} = {toString() {
        let target = this;
        if (this == toString) target = origToString;
        if (this == error) target = origError;
        return origToString.call(target);
    }};
    Function.prototype.toString = toString;
    Console.prototype.error = error;
}

Is there any way override a function such that it is not possible to detect the function was overriden?

I think the answer here is "no". Your best bet is to use a Proxy, but there will always be some way to detect that the code was monkey-patched.

The real "solution" would be to change the runtime to prevent the program from knowing it had been patched.

It really depends what you're doing and to what lengths the other party will go to in order to detect whether the code was modified. There's probably a term for this (does anyone know?), but I'll call this adversarial programming until someone proposes a more correct term.

Related