javascript - 从 Chrome 扩展执行跨源请求时的 XMLHTTPRequest 漏洞?
问题描述
您可以使用 Chrome 扩展程序进行跨源请求。我创建了一个测试 Chrome 扩展来解决这个问题。它通过单击按钮从站点获取特定页面中的所有代码。
我从页面中想要的只是数据(只是一些文本和数字),然后将其显示在扩展的选项页面中。
我提取这些数据的方式是遍历响应中的文档(请求的response
orresponseXML
属性)。比如我querySelectorAll
用来获取一堆元素,然后我把它们的所有textContent
属性放在一个数组中,然后我把数组上的每个元素放在<ul>
扩展页面的 DOM 中的 a 中。
最后,在我从站点请求特定页面后,我将响应文档存储在我的localStorage
(仅存储请求的最后一页,覆盖存储的前一页)。我通过存储outerHTML
响应元素(通过document.documentElement.outerHTML
)来做到这一点。然后,当我刷新扩展页面时,我使用DOMParser
andparseFromString
将其转换回文档。在它被转换回文档之后,上一段中的内容再次发生(DOM 遍历和数据提取)。
任何潜在的安全问题?
MDN 是这样说的:
“处理包含 HTML 文档的 responseText 属性 如果您使用 XMLHttpRequest 获取远程 HTML 网页的内容,则 responseText 属性是一个包含原始 HTML 的字符串。这可能难以操作和分析。有三种主要分析方法并解析这个原始的 HTML 字符串:
- 使用文章 https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/HTML_in_XMLHttpRequest中介绍的 XMLHttpRequest.responseXML 属性
XMLHttpRequest 中的 HTML。通过 fragment.body.innerHTML 将内容注入到文档片段的正文中,并遍历片段的 DOM。
如果您总是事先知道 HTML responseText 的内容,则可以使用 RegExp。如果您使用 RegExp 扫描换行符,您可能想要删除换行符。但是,此方法是“最后的手段”,因为如果 HTML 代码稍有更改,该方法可能会失败。”
我正在使用第一种方法。
此页面讨论了处理响应的危险和安全方法(尽管这里讨论的是 responseText,而不是从 response 或 responseXML 获得的 html 文档): https ://developer.chrome.com/apps/xhr
概括:
// 1. WARNING! Might be evaluating an evil script!
var resp = eval("(" + xhr.responseText + ")");
// 2. WARNING! Might be injecting a malicious script!
document.getElementById("resp").innerHTML = xhr.responseText;
// 3. JSON.parse does not evaluate the attacker's scripts.
var resp = JSON.parse(xhr.responseText);
// 4. innerText does not let the attacker inject HTML elements.
document.getElementById("resp").innerText = xhr.responseText;
这里唯一的问题是第 2 个问题。我使用 innerHTML 来创建一个带有来自响应文档的数据的<li>
's 。<ul>
现在,我知道这个站点,但我想我可以将其更改为不使用 innerHTML。
解决方案
安全 API/属性:
textContent
或innerText
绝对安全responseXML
是安全的,请参阅XHR 规范中的第 5 步:对接收到的字节禁用脚本支持
DOMParser
API 同样是安全的。
可能不安全:
innerHTML
不会运行<script>
元素,请参阅(HTML5 规范):当使用innerHTML 和outerHTML 属性插入时,它们根本不执行。
但它会在事件处理程序属性中运行内联代码,
<img src="x" onerror="alert(1)">
虽然通常这不会在扩展页面中运行,因为默认 CSP禁止扩展页面中的内联代码,但许多作者需要放松 CSP。即使您没有放宽默认 CSP 并希望在主文档中使用原始的外部 html,您也需要剥离
<style>
和<link>
元素,因为它们会改变主页外观、删除on
属性、<script>
元素(只是为了保持一致性) . 或者将该 HTML 放在具有属性的iframe 中。sandbox
还有 Mozilla 的政策需要考虑:
如果您的项目将接受任何形式的安全审查,那么使用 innerHTML 很可能会导致您的代码被拒绝。例如,如果您在浏览器扩展中使用 innerHTML 并将扩展提交到 addons.mozilla.org,它将不会通过自动审核过程。
推荐阅读
- object - 对象检测并发送通知
- javascript - 获取从 SQL 表到角度表的确切日期和时间
- css - 在 SCSS 中使用嵌套时,最佳实践是什么?
- python-3.x - 使用其他字典中的字典值创建字典
- terraform - terraform-provider-vsphere 自定义 windows ip 地址失败 sysprep “Windows 安装程序无法配置 Windows 以在此计算机的硬件上运行”
- docker - 从 Docker 中的用户输入发送 GET 请求?
- python - Pandas - 根据唯一值和不同列日期时间过滤 DataFrame
- tsql - 如何通过在 sql server 中执行另一个变量来打印变量值?
- c++ - 有没有办法在 R 中做 C++ 代码的调用图?
- javascript - 首次加载时选择 JQuery 的填充选项的初始值