I'm attempting to create an undetectable method of overriding the Error object in JavaScript without triggering standard detection mechanisms. My goal is to modify the Error prototype or constructor in a way that cannot be easily identified by typical inspection techniques.
I've explored multiple strategies for overriding the Error object:
- Using
Proxy - Arrow Function
- Long Function(
Error=function(){}) - Short Function(
Error={Error(){}}.Error)
I've developed a comprehensive test function to validate the stealth of the override:
function testError(){
if(Object.hasOwn(Error,"caller") || Object.hasOwn(Error,"arguments") || Object.hasOwn(Error,"prepareStackTrace"))
return false;
try {
new Error()
} catch (error) {
return false;
}
try {
Error()
} catch (error) {
return false;
}
try {
Object.create(Error).toString()
} catch (error) {
if(error.stack.includes("Object.toString"))
return false
}
return Error.isError(new Error) && new Error() instanceof Error && new TypeError() instanceof Error && Error() instanceof Error && TypeError() instanceof Error
}
What techniques can successfully bypass these detection mechanisms and pass the provided testError() function?
Current challenges:
- Most standard override techniques are easily detectable
- Need a method that doesn't trigger standard inspection checks
ErrororError.prototype? Given something like ...class MyError extends Error { constructor(...args) { super(...args); /* custom implementation */ } }... for instance is good enough for being detected via ...Error.isError(new MyError). And for the matter of monkey patching, in order to provide a good approach/solution one needs to know whetherErrororError.prototypeor both are going to be patched.Error.prepareStackTrace, for this Error needs to be overridden, custom error solution is not. And the main problem here is thatErrorneeds to be overridden. there is no problem inError.prototypeErrortype/constructor is going to breakinstanceofoperator based detection of sub-error types like e.g.SyntaxErrorinstances. What definitely was worth a try is augmenting/patchingError.prototypeviaObject.defineProperty.Errorhas been tampered with. At this point there wouldn't really be a "standard" anything. It's exceptionally abnormal to not trustError. And if the code already doesn't trust it, then there are a million things it might be trying to check. Including many that are flawed (no-ops or with high chance of producing false positives or false negatives)Erroroverride. Is it possible to manipulate the error stack trace without overridingError?