Javascript 在Chrome扩展中拦截本地存储时如何防止堆栈溢出

Javascript 在Chrome扩展中拦截本地存储时如何防止堆栈溢出,javascript,html,google-chrome,google-chrome-extension,local-storage,Javascript,Html,Google Chrome,Google Chrome Extension,Local Storage,我正在尝试向所有本地存储键添加一个“选项卡名称空间”,以便在多个选项卡之间实现站点本地存储的唯一性 在一个简单的HTML5页面中,假设一个网页具有以下脚本: Storage.prototype._setItem = Storage.prototype.setItem; Storage.prototype.setItem = function(key, value) { console.log("intercepted set local storage " + key + " = " +

我正在尝试向所有本地存储键添加一个“选项卡名称空间”,以便在多个选项卡之间实现站点本地存储的唯一性

在一个简单的HTML5页面中,假设一个网页具有以下脚本:

Storage.prototype._setItem = Storage.prototype.setItem;
Storage.prototype.setItem = function(key, value) {
    console.log("intercepted set local storage " + key + " = " + value);
    this._setItem(key, value);
}

Storage.prototype._getItem = Storage.prototype.getItem;
Storage.prototype.getItem = function(key) { 
    console.log("intercepted get local storage " + key);
    return this._getItem(key);
}
这使用户有机会截获本地存储的所有get/set

现在让我们假设您有一个做同样事情的扩展:

var actualCode = `Storage.prototype._setItem = Storage.prototype.setItem;
Storage.prototype.setItem = function(key, value) {
    console.log("intercepted set local storage " + key + " = " + value);
    this._setItem(key, value);
}

Storage.prototype._getItem = Storage.prototype.getItem;
Storage.prototype.getItem = function(key) { 
    console.log("intercepted get local storage " + key);
    return this._getItem(key);
}

console.log("local storage get/set injector completed");
`;

var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
当使用上面的脚本加载页面时启用此扩展时,将出现堆栈溢出:

Uncaught RangeError: Maximum call stack size exceeded
at Storage.getItem [as _getItem] (<anonymous>:48:37)
at Storage.getItem [as _getItem] (<anonymous>:50:17)
at Storage.getItem [as _getItem] (<anonymous>:50:17)
at Storage.getItem [as _getItem] (<anonymous>:50:17)
at Storage.getItem [as _getItem] (<anonymous>:50:17)
at Storage.getItem [as _getItem] (<anonymous>:50:17)
at Storage.getItem [as _getItem] (<anonymous>:50:17)
at Storage.getItem [as _getItem] (<anonymous>:50:17)
at Storage.getItem [as _getItem] (<anonymous>:50:17)
at Storage.getItem [as _getItem] (<anonymous>:50:17)
未捕获范围错误:超过最大调用堆栈大小
at Storage.getItem[as _getItem](:48:37)
at Storage.getItem[as _getItem](:50:17)
at Storage.getItem[as _getItem](:50:17)
at Storage.getItem[as _getItem](:50:17)
at Storage.getItem[as _getItem](:50:17)
at Storage.getItem[as _getItem](:50:17)
at Storage.getItem[as _getItem](:50:17)
at Storage.getItem[as _getItem](:50:17)
at Storage.getItem[as _getItem](:50:17)
at Storage.getItem[as _getItem](:50:17)

是否有某种方法可以检测到有人已经执行了拦截的本地存储并防止该问题

如果我将此代码放在扩展名内的普通js文件中,则无法复制。不清楚为什么要将此代码作为内联脚本元素附加到扩展页中,而内联脚本元素甚至不会运行,除非您放松默认的CSP(坏主意;最好使用沙盒页面)。我还认为最好使用
Proxy
API,因为getItem不会像
localStorage.foo
那样被直接访问调用。我来看看
Proxy
api你知道有类似的例子吗?通过我更新上述问题的方式,它看起来相当不平凡。它只是在执行stackoverflow,因为我正在加载的htmlpage也有相同的原型hack。将之前的getItem引用保存在局部变量中(可能在闭包中)。这就是当你的方法是嗯。。。生活在边缘!