哪些糟糕的编码实践使浏览器扩展易受攻击?

信息安全 网页浏览器 javascript 漏洞扫描器 审计 浏览器扩展
2021-08-16 08:50:59

我正在尝试使用 JSHint 扫描 JavaScript 文件中的漏洞。具体来说,我正在扫描浏览器扩展的 JavaScript 文件。为了寻找可能的漏洞,我正在寻找糟糕的 JavaScript 编码实践,例如使用eval. (JSHint 可以选择检测eval.)

我目前正在扫描良性扩展,我将研究可能以某种方式危及用户安全的漏洞(可能是微不足道的)。但是,我不知道eval我还应该寻找什么(除了使用、未使用和未定义的变量)。

有人可以建议我应该寻找什么吗?

3个回答

在浏览器扩展中,漏洞的影响很大程度上取决于上下文和请求的权限。存在用于检查代码的静态工具(JSHint、AMO 验证器),但它们都不是 100% 可靠的,尤其是对于混淆代码。

因此,我不会展示一个神奇的正则表达式来告诉您某些代码是否易受攻击,而是简要概述扩展的工作原理,以及一小部分潜在的扩展特定问题。

现有工具

Mozilla 在 addons.mozilla.org 上使用的静态代码分析工具作为AMO Validator公开提供。该工具适用于所有基于Jetpack的附加组件。首先,它识别(通过哈希)并排除所有列入白名单的 JS 库。然后,它在 XPI 存档的剩余内容上运行这些测试用例。

其他供应商都没有发布过这样的工具。幸运的是,Chrome / Safari / Opera 的扩展(不是插件)无法获得与 Firefox 附加组件一样多的权限。

提取

Firefox (xpi) 和 Opera (oex) 附加组件是具有不同扩展名的 zip 文件。
Chrome (crx) 扩展是带有前面CRX 标头的 zip 文件。
Safari (safariextz) 扩展是签名的 xar 档案。

7-zip能够提取所有这些档案。

权限

Chrome、Safari 和 Opera 要求扩展开发者声明访问某些来源或功能的权限。这些声明可以在以下位置找到:

无法在 Firefox 附加组件中配置源访问。

内容脚本/注入脚本

所有扩展环境都支持在与预定义 URL 模式匹配的页面上执行代码。这些在 Chrome / Firefox 中称为内容脚本,在 Opera / Safari 中称为注入脚本。这些脚本可以直接访问页面的 DOM,但不能直接访问页面的 JavaScript 变量,因为执行上下文不同。

背景页面

这些页面是扩展程序中最特权的部分。

漏洞

我不会提到明显的错误,例如使用setTimeout字符串(这些已经在 bobince 的回答中提到),或者不太可能是偶然的牵强的方法,例如从页面获取凭据并将其发送到的扩展流氓网络服务。

  • 使用.innerHTMLjQuery 或 jQuery 解析外部HTML(请参阅Stack Overflow 上的这个问题):

    // Example 1:
    var heading = $(xhr.responseText).find('h1').text();
    // Example 2:
    document.body.innerHTML += '';
    // For: <img src="bogus" onerror="do_something_evil_with_privileges()">
    
  • window.onmessage不验证数据或检查的情况下使用事件event.origin在以下示例中,任何第三方都可以使用window.openpostMessage向 Gmail 发送邮件,并滥用无意泄露的功能:

    // Content script running on https://mail.google.com/mail/
    addEventListener('message', function(event) {
        if (event.data.type === 'send-mail') doSomething();
        // or:
        notifyBackgroundPage(event.data);
    });
    
  • 加载外部 (JS) 代码(更糟糕的是:通过 http 加载外部代码)。如果外部来源受到威胁,所有用户都将容易受到滥用。

  • 使用CrossriderKango等跨浏览器扩展框架这些对开发人员来说很方便,但生成的扩展会请求不必要的权限。

  • 没有充分限制扩展 API 的影响。一个极端的例子:删除httpOnly所有站点的 cookie 标志,而不仅仅是相关站点。这还包括在太多页面上运行内容脚本。

  • 隐私问题:

    • 使用 Google Analytics 等服务(搜索_gaq.push
    • 加载外部资产,例如社交媒体按钮。

大多数正则向量也与扩展相关。使用https://www.owasp.org/上的备忘单或查看http://html5sec.org/

从 JS 注入 JS 的常用方法。

几乎在所有情况下都是错误的:

  • eval
  • new Function()
  • setTimeoutsetInterval带有第一个参数的字符串
  • setAttribute(或等效的框架,例如attr())在on...事件处理程序属性(或变量属性名称)上
  • javascript: 网址

在有限的情况下可能是必要的,但应保持在最低限度,并对其余情况进行仔细审核:

  • createElement('script') 并设置正文
  • 将变量外部 URL 分配给<script><link>
  • 通过 HTML 注入 - 设置innerHTML为使用非转义变量创建的字符串,例如div.innerHTML= '<p>'+message+'</p>'. 通常最好用 DOM 风格的内容创建方法代替(特别是给定一个框架以使其变得容易);对于某些情况,例如巨大的长表,可能需要涉及创建标记的解决方案
  • 隐藏在框架函数后面的 HTML 注入,例如使用字符串参数调用的任何 jQuery 操作函数(、、等)(改用.html()快捷.append()方式.before()$('<div>', {dynamic attributes})

在某些情况下可能是不可避免的,但需要检查:

  • location在导航、创建链接或设置 image/object/iframe/etc src(或new Image(), 或 CSSurl()属性)时使用可变 URL 。存在危险的 URL 方案(包括但不限于javascript:),因此需要将这些方案列入白名单。这是浏览器扩展中非常常见的问题,通常最终会导致通用 XSS
  • 元素/属性中内容集的 CSS 注入style(使用绑定和表达式等危险属性提升为 JS 注入)  

我不确定它将如何应用于浏览器扩展,但在网络应用程序中,我通常会寻找与变量连接的硬编码字符串。这通常不是问题,但它可以帮助我找到从原始用户输入创建 HTML 的位置。例如,代码可能如下所示:

var myHtml = "<h1>" + userinput + "</h1>";

这是不安全的,因为用户输入可能包含 HTML(包括脚本),并且在以这种方式使用之前应该是 HTML 转义。

这是一个正则表达式,用于查找硬编码字符串与变量连接的情况:

["']\s*\+|\+\s*["']