我目前正在从事安全非常重要的项目。默认情况下,所有全局变量/属性(例如Promise
甚至crypto
都可以被覆盖。
有没有一种方法可以防止它们被覆盖?
示例:
window.crypto.getRandomValues = () => { return [1] }
window.crypto.getRandomValues(new Uint32Array(1))[0] // 1
我的第一个想法是使用Object.freeze()
来锁定对象,但是可以简单地覆盖Object.freeze
方法,使其无所事事。
我们已经非常选择了我们使用的依赖项,但是我仍然要确保这些变量不会被覆盖。或者至少检测它们是否被覆盖。
答案 0 :(得分:0)
免责声明:这只是一个粗略的轮廓,未经彻底测试。我确定还有更多问题要解决。
freezing窗口对象不是选项,这只会引起问题,但是可能像window.crypto
这样的对象?
但是您可以重新定义属性,使其即使在窗口对象上也无法更改
function freezeProp(target, propertyName) {
const { value, get = () => value, set = () => void 0, ...desc } = Object.getOwnPropertyDescriptor(target, propertyName);
Object.defineProperty(target, propertyName, { ...desc, get, set, configurable: false });
}
freezeProp(window, "crypto");
但是,只有在可以确保您是第一个运行的脚本的情况下,这些方法才可行。
如果您引用了某些方法,也可以确定它们是否已更改;而我们又回到了第一个运行的脚本。
但是,如果您不确定全局范围是否已被破坏,为什么不获取一个新的窗口对象?
window.crypto.getRandomValues = () => {
return [1]
};
const secure = (() => {
let iframe = document.createElement("iframe");
document.body.appendChild(iframe);
const contentWindow = iframe.contentWindow;
document.body.removeChild(iframe);
return contentWindow;
})();
var a = window.crypto.getRandomValues(new Uint8Array(1));
console.log(a);
var b = secure.crypto.getRandomValues(new Uint8Array(1));
console.log(b);