Bri*_*itt 14 javascript browser
这个问题是关于属性disguiseToken本身,而不是直接关于错误。
disguiseToken没有出现在代码库中,谷歌搜索也没有出现任何东西。
disguiseToken?调用时发生错误getOwnPropertyDescriptor。
示例堆栈跟踪:
TypeError: Cannot read property 'disguiseToken' of undefined
at getOwnPropertyDescriptor (eval at (:1:38695), :560:24)
at Function.Object.getOwnPropertyDescriptor (https://www.mywebsite.com/polyfills.d8680adf69e7ebd1de57.js:1:39700)
at a (https://www.mywebsite.com/main.25a9fda6ea42f4308b79.js:1:1075141)
at https://www.mywebsite.com/5.6c58d8732681a35a1f8b.js:1:1533
at Object.26NW (https://www.mywebsite.com/5.6c58d8732681a35a1f8b.js:1:1805)
at i (https://www.mywebsite.com/runtime.8928e149b3f1200cf1ca.js:1:507)
at Module.L6id (https://www.mywebsite.com/5.6c58d8732681a35a1f8b.js:1:62181)
at i (https://www.mywebsite.com/runtime.8928e149b3f1200cf1ca.js:1:507)
at https://www.mywebsite.com/main.25a9fda6ea42f4308b79.js:1:914848
at t.invoke (https://www.mywebsite.com/polyfills.d8680adf69e7ebd1de57.js:1:8160)
at M (https://www.mywebsite.com/polyfills.d8680adf69e7ebd1de57.js:1:14076)
at M (https://www.mywebsite.com/polyfills.d8680adf69e7ebd1de57.js:1:13634)
at https://www.mywebsite.com/polyfills.d8680adf69e7ebd1de57.js:1:14864
at t.invokeTask (https://www.mywebsite.com/polyfills.d8680adf69e7ebd1de57.js:1:8844)
at Object.onInvokeTask (https://www.mywebsite.com/main.25a9fda6ea42f4308b79.js:1:467756)
at t.invokeTask (https://www.mywebsite.com/polyfills.d8680adf69e7ebd1de57.js:1:8765)
at e.runTask (https://www.mywebsite.com/polyfills.d8680adf69e7ebd1de57.js:1:4026)
at g (https://www.mywebsite.com/polyfills.d8680adf69e7ebd1de57.js:1:11111)
Run Code Online (Sandbox Code Playgroud)
此错误发生在具有不同引擎的多个浏览器中。在过去的 3 个月中(今天是 2020-06-13),我们已经在:
更新(1):
我完全理解错误的含义。我的问题是什么是“伪装令牌”?我从来没有听说过,这不是我的代码中的东西。我在我的整个代码库中搜索了“伪装”这个词,没有找到,所以它一定是 Angular 内部的东西。这是什么鬼?我每天收到几十次这个错误,但我不知道它是什么。我正在运行 Angular 7。
查看angular 和 angular.js的源代码并没有给出任何结果disguiseToken
更新(2):
此代码会产生与错误报告中看到的完全相同的错误消息。此代码段并非取自实际源代码。它包含在此处,以便其他人可以重现该错误。
<script type="application/javascript">
try {
class Dummy extends HTMLElement {
get dummyFuncA() {
return 'dummy';
}
}
var old = Object.getOwnPropertyDescriptor;
Object.getOwnPropertyDescriptor = function(obj, property) {
var descriptor = old.call(this, obj, property);
var _disguiseToken = descriptor.disguiseToken;
return descriptor;
};
var descriptorA = Object.getOwnPropertyDescriptor(Dummy.prototype, 'dummyFuncA');
var descriptorB = Object.getOwnPropertyDescriptor(Dummy.prototype, 'dummyFuncB');
} catch (err) {
console.warn(err);
}
</script>
Run Code Online (Sandbox Code Playgroud)
此代码段本身可用于测试是否Object.getOwnPropertyDescriptor已被覆盖:
<script type="application/javascript">
try {
class Dummy extends HTMLElement {
get dummyFuncA() {
return 'dummy';
}
}
var descriptorA = Object.getOwnPropertyDescriptor(Dummy.prototype, 'dummyFuncA');
var descriptorB = Object.getOwnPropertyDescriptor(Dummy.prototype, 'dummyFuncB');
} catch (err) {
if (
err &&
err.toString &&
err.toString().indexOf('Cannot read property \'disguiseToken\' of undefined') > -1
) {
console.log('Something did override \'Object.getOwnPropertyDescriptor\'');
console.warn(err);
console.log(Object.getOwnPropertyDescriptor);
}
}
</script>
Run Code Online (Sandbox Code Playgroud)
更新(3):
我们添加了上述内容,但没有学到太多:/
登录console.log(Object.getOwnPropertyDescriptor);:
function getOwnPropertyDescriptor() { [native code] }
Run Code Online (Sandbox Code Playgroud)
所以这似乎没问题。
我们还添加了日志,以便script在发生此错误时将所有标记源 url 或 innerHTML 发送到我们的错误报告服务。这没有产生任何意外的结果。
更新(4):
我们添加了代码和日志来捕获Proxy. 这不是我们在代码库中使用的东西,理论上这也可能是这个问题的一部分。
几个小时后,我们遇到了一些问题,似乎确实有什么东西正在注入创建 Proxy's 的。这是在这些页面上运行的不是我们的代码的第一个直接证据。
当某些东西试图构造一个时捕获的堆栈跟踪Proxy:
[redacted-url]:72:24
[redacted-url]:356:25 ObjectWithDefaultValues
[redacted-url]:404:59 parseMetaTags
[redacted-url]:453:18
[redacted-url]:465:3 global code
Run Code Online (Sandbox Code Playgroud)
带 line 的第一行72是我们调用的地方new Error()。行356-456不是我们的代码,而是注入的东西。
我们用来检测Proxy使用的代码:
<script type="text/javascript">
var proxyUses = [];
function reportProxyUse() {
if (true) { // [redacted] check if error reporting is ready
for (var i = 0; i < proxyUses.length; i++) {
console.log('target', proxyUses[i].target);
console.log('handler', proxyUses[i].handler);
// [redacted]
// error reported here
}
proxyUses = [];
} else {
setTimeout(function() {
reportProxyUse();
}, 2000);
}
}
window.Proxy = function( target, handler ) {
proxyUses.push({
'target': target,
'handler': handler,
'error': new Error() // this captures a stack trace
});
reportProxyUse();
return target;
};
</script>
Run Code Online (Sandbox Code Playgroud)
我们将添加一个MutationObservernext 来尝试捕获所有脚本。甚至那些删除自己的人。
更新(5):
尚未完全分析这一点,但似乎 Safari 中的“添加到阅读器列表”会执行页面的初始渲染并注入包含这些Proxy内容的 Javascript 。
由于这显然只是 Safari 的使用,Proxy上面的堆栈跟踪没有解释disguiseToken。
陪审团仍然在那里。只是总结一下当前的状态和评论:
disguise+ eval+ 页面上用户没有发现任何错误 + 无法找到该字符串。所有这些都意味着恶意 npm 包的可能性。由于代码可能很混乱,这就是搜索不会产生disguiseToken任何结果的原因。跑步npm install就是你获得它所需要的一切。有时,即使是受人尊敬的包裹也会被劫持。
但还有一些其他的可能性
https,至少在某些国家(哈萨克斯坦)仍然是可能的。或者也许是在企业网络中。似乎已经发现问题出现在自己的代码库之外。但这从一开始就众所周知。
看起来问题是从 a 内部产生的Proxy。但这不是必要的,所以从我们现在在问题中可以看到:
Proxy并不意味着从该 抛出错误Proxy。target,所以您不应该看到该错误。Proxy造成麻烦的原因可以做什么?一些开放性问题:
try-catch日志,它将仅捕获代码及其依赖项内部的错误(意味着恶意 npm 包)。window.onerror- 它可以捕获一些注入脚本中的错误(那些在设置处理程序后注入并抛出的错误)window.onerrorMutationObserver可以捕获仅在设置后注入的脚本,以及仅从页面上已存在的脚本注入的脚本。这又意味着 -在代码的依赖项内部。它不会捕获MiM脚本,因为在这种情况下,用户加载其脚本已存在的页面。所以你可能<head>也应该记录。页面加载后立即。以及关于错误。(但是脚本也可以注入到 HTML 末尾或其他地方)。我认为我们没有做出任何更改来解决此问题,它已关闭,因为它停止在 Sentry 中被拾取。我猜供应商更新解决了根本问题。
| 归档时间: |
|
| 查看次数: |
892 次 |
| 最近记录: |