【问题标题】:How to detect or prevent built-in browser functions from being replaced?如何检测或防止内置浏览器功能被替换?
【发布时间】:2022-07-07 13:17:04
【问题描述】:

我今天注意到我可以像这样替换一个敏感的内置 JS 函数:

async function _hackedEncrypt(algorithm, key, data) {
   console.log('hacked you!');
}

const subtle = global.crypto.subtle; // Assign to get around "read-only" error.
subtle.encrypt = _hackedEncrypt;

global.crypto.subtle.encrypt(); // 'Hacked you!' appears in console.

哎呀!

这个漏洞利用非常简单。我的 Web 应用程序中的数千个依赖项(直接和传递)中的任何一个都可以重新分配此功能。请注意,我的问题并非特定于 Web Crypto - 它只是攻击者更危险的目标之一。

我怎样才能检测到该函数已被重新分配或保证我总是调用它的原始浏览器实现?

【问题讨论】:

  • 运行一种病毒会危及您的整个系统。不要有数千个依赖项。
  • 一个空的create-react-app 在你添加一行代码之前会带有1380个依赖。因此,对于我选择的平台,一个非常受欢迎的平台,我无法接受您的建议。
  • 我在写react,我从来没有用过create-react-appreact 本身(因为最近提交)将具有零依赖关系,react-dom 仍然有两个。
  • 你的观点有道理。我仍在寻找一种解决方案,它不依赖于信任我的直接和传递依赖项,不会让我暴露于这个漏洞。
  • 您指的是供应链攻击。如果你有一个受损的依赖项,它可以通过注册回调来虹吸用户信用卡等,而无需替换内置的 JS 函数。有dedicated security products for protecting against supply chain attacks

标签: javascript security dom websecurity


【解决方案1】:

在我的index.js 中,我先于任何其他模块导入此模块。它必须是第一次导入,这样其他依赖项才有机会替换函数,然后我才能设置对原始的引用。

const originalEncrypt = global.crypto.subtle.encrypt;
// Any number of functions worth protecting can be added here
// and also added to the check in wereFunctionsReplaced().

function wereFunctionsReplaced() {
  return global.crypto.subtle.encrypt !== originalEncrypt;
}

...然后我在我担心的函数调用之前调用wereFunctionsReplaced()

if (wereFunctionsReplaced()) throw Error('Everybody run to the panic room!');
global.crypto.subtle.encrypt(algorithm, key, data);

当然,我也可以像这样包装受保护的函数:

function safeEncrypt(algorithm, key, data) {
  if (wereFunctionsReplaced()) throw Error('Everybody run to the panic room!');
  return global.crypto.subtle.encrypt(algorithm, key, data);
}

在某些情况下,将内置函数存储到变量中并直接从变量调用函数比从global.* 调用更方便。但是对于crypto.subtle.encrypt,它会在 Chrome 中引发“错误调用”错误。仔细想想,许多微妙的、意想不到的行为可能是由于在全局层次结构中的预期位置之外调用内置函数造成的。

这是后代的自我答案。但我很想听到比这个更好的解决方案。也欢迎批评此解决方案可能存在的任何错误。

【讨论】:

  • 缺点:wereFunctionsReplaced() 函数本身可以被替换。但是,它不太可能成为从第 3 方依赖项发起的攻击的目标。
  • 如果您希望通过默默无闻来获得安全性,因为您与标准的差异足够大,因此未适应的恶意软件可能会偶然发现您的代码,您可能需要查看 Object.freeze 和 @ 987654322@。再次注意,我不相信有任何东西可以保护您免受适用于您的情况的恶意软件的侵害 - 总会有一些漏洞可以滥用。
【解决方案2】:

您所描述的是更广泛的攻击类别的一个子集:Supply Chain Attacks

基本的想法是我创建一个有用且微不足道的 JS 库,随着时间的推移,大量项目依赖它,然后我插入一个后门,下次他们升级它们是依赖项 - 我可以访问他们的用户的浏览器。
然后我可以窃取密码、信用卡信息、PII 等 - 基本上是数字略读。 Magecart 可能是 JS 领域最著名的攻击。一般而言,最著名的可能是Solarwinds attack

一种解决方案是自己动手。这几乎是没有希望的,因为即使您可能知道您使用了哪些 API,但您不知道您的依赖项使用什么以及它们如何变化。

另一个解决方案是Content Security Policy,它控制传出请求:撇渣器可能已经能够将他们的代码放入您的应用程序中,但如果您的内容安全策略不允许它发出请求,他们就无法做任何有用的事情未知主机。

也有商业解决方案。我知道:

【讨论】:

    猜你喜欢
    • 2012-01-20
    • 1970-01-01
    • 2014-08-03
    • 2011-03-26
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 2013-10-06
    • 2015-12-04
    相关资源
    最近更新 更多