问题
I want to replace Date inside a JavaScript VM (V8 but this is not specific to V8), and make it impossible to access the original Date constructor. This is meant to be one part of a defence against timing attacks like Spectre with multi-tenant JavaScript running in the same process (but different JavaScript VM.) The idea is to deny access to high resolution timers. Cloudflare does this in their Workers, for the same reason. Time is advanced only when IO happens, not during computation. I know there are other ways to construct a timer, but I'm just focused on Date for this question.
I think this can be done in pure JavaScript, and this is my attempt. Is there a way to get the original Date constructor back after running this? Is there a way this differs functionally from the builtin Date - something that could break backwards compatibility?
// Current UNIX timestamp in milliseconds, but that we set manually on each call to runTasks.
// not advancing time during computation is one of our defenses against Spectre attacks.
let NOW = Date.now();
export function setDate(unixTimestampMillis) {
NOW = unixTimestampMillis;
}
Date = function (BuiltinDate) {
function Date(...args) {
if (new.target === undefined) {
// This is the deprecated naked Date() call which returns a string
return (new BuiltinDate(NOW)).toString();
}
// Otherwise it was the constructor called with new
if (args.length === 0) {
// Return the "current" time.
return new BuiltinDate(NOW);
}
// Build a Date with the specified datetime
return new BuiltinDate(...args);
}
// Make a copy of the BuiltinDate "class" and replace the constructor,
// It needs to be impossible for the user to grab an reference to BuiltinDate.
Date.prototype = BuiltinDate.prototype;
BuiltinDate.prototype.constructor = Date;
// Add the static methods now(), UTC(), and parse() - all of which return a numeric timestamp
function now() {
return NOW;
}
Date.now = now;
Date.parse = BuiltinDate.parse; // returns a number
Date.UTC = BuiltinDate.UTC; // returns a number
return Date;
}(Date);
来源:https://stackoverflow.com/questions/64625568/replace-builtin-date-without-being-able-to-recover-original-constructor