简体中文

开发者工具 · URL 编码器和解码器

URL 编码不是净化:解码后的参数仍然需要转义

· 为什么它很重要

url 编码 安全 xss

百分比编码的有效负载解码回原始形式,准备输出转义
原始 ToolAcre 矢量图

百分比编码保护 URL 结构,而不是 HTML、SQL 或 shell。这篇文章解释了为什么正确编码的值在解码时再次变得危险,以及哪种转义属于哪里。

为什么仅靠 URL 编码无法阻止 XSS 攻击

如果对传输进行编码但在渲染之前进行解码,“安全”参数可以运行脚本。考虑像 img 标签这样的 XSS 有效负载,其 onerror 处理程序百分比编码为 %3Cimg%20src%3Dx%20onerror%3Dalert%281%29%3E。如果它在 URL 中传输并在插入 HTML 之前由应用程序代码解码,则浏览器会看到原始标记并执行处理程序。 Percent-encoding是表示层;不会改变潜在的威胁。

有效负载仅在传输过程中是安全的,此时它是对 HTTP 或 URL 解析器没有特殊含义的编码字符串。一旦它被解码,它就会再次变得危险,因为它会恢复到原来的形式。每个下游上下文必须应用适合其使用数据方式的自己的转义规则。 URL 编码不能替代 HTML 转义、SQL 参数化或 shell 参数处理。

百分比编码的用途是什么——保持线路上的分隔符明确,仅此而已

百分比编码的作用是精确保护 URL 结构。 & 符号仍然是查询字符串语法的一部分,不会被重新解释为分隔符。斜杠不会成为路径分隔符。问号不开始片段。通过将保留字符编码为 %XX,解析器将它们视为数据,而不是语法。这适用于一项工作:保持网络上的 URL 结构明确。

解码完全颠倒了单向街道。恢复的字节正是编码的内容,不多也不少。 HTML 危险字符串仍然是危险的,SQL 注入向量仍然是危险的,shell 命令仍然是危险的。百分比编码不是输入验证,不是清理,也不是安全边界。它只是表示格式。

解码恢复原始字节 - 因此每个下游上下文再次看到原始值

特定于上下文的转义才是真正的保护所在。 HTML 上下文需要实体:小于变为 <,大于变为 >,引号变为 ",& 变为 &。SQL 上下文需要参数化查询,将结构与数据分开,防止攻击者突破。Shell 上下文需要参数数组,完全避免分词和通配。

每个上下文都有不同的危险特征和不同的逃逸规则。 HTML 实体在 SQL 查询中是无害的,但对于那里的保护毫无用处。反斜杠可以防止某些数据库中的 SQL 注入,但不能防止其他数据库中的 SQL 注入。 Shell 转义取决于引用风格。开发人员在选择如何处理数据之前必须了解目的地。

上下文特定的转义 — 用于标记的 HTML 实体、用于 SQL 的参数化查询、用于 shell 的参数数组

工作示例:跟踪从链接到日志到页面的有效负载揭示了编码和转义必须发生的位置。链接包含编码的 XSS 有效负载作为查询参数。服务器收到的数据仍然编码在 HTTP 请求正文中。应用程序解码查询参数以将其显示在页面中。如果没有输出转义,浏览器会将有效负载呈现为 HTML 并执行它。

如果相同的参数记录到文件中,则日志条目清楚地包含解码的有效负载。第二个应用程序读取日志,再次解码,将其插入 HTML 页面而不转义。有效负载第二次执行。在每一步中,上下文决定什么是安全的。 URL 解码是安全的。文件存储是安全的。但不转义的 HTML 输出是致命的。

工作示例:跟踪从链接到日志到页面的一个有效负载 - 在哪里编码、在哪里解码、在哪里必须转义

编码作为过滤器规避工具说明了为什么攻击者会进行双重编码并显着混合十六进制大小写。如果防火墙查找 img 标签,攻击者会发送 %3Cimg 并希望应用程序解码一次,但防火墙不会。如果验证拒绝 %3Cimg 但允许不同的情况,则相同的字节解码为相同的负载。依赖于模式匹配编码输入的安全性很脆弱。

解码必须准确且绝对可预测。规范形式(小写十六进制,已知编码)允许一致的策略,但不能解决根本问题。唯一可靠的方法是允许在必要时进行解码,并在使用前立即应用上下文特定的输出转义。解码从来都不是安全的;仅是传输所必需的。

编码作为过滤器规避工具 - 为什么攻击者进行双重编码并混合十六进制大小写,以及为什么解码必须准确

完整的 XSS 防御需要完全了解数据流、每个步骤所经过的上下文、以及转义每个上下文所需的内容。 URL 编码是一小部分:仅在传输过程中保留结构。但一件作品本身并不是防御。许多开发人员将编码与清理混为一谈,因为两者都涉及替换字符,但服务于完全不同的重要工作。

Web 应用程序防火墙可以检测请求负载中的模式,但编码很容易逃避简单的模式匹配技术。 WAF 调整非常复杂,超出了 URL 编码的范围。可靠的防御是应用程序代码中的输出转义,与对您的特定上下文和要求有意义的输入验证相结合。

这不包括什么 - 完整的 XSS 防御指南或 Web 应用程序防火墙调整

完整的 XSS 防御需要完全理解数据流、每个步骤所经过的上下文、整个应用程序中每个上下文需要什么转义。 URL 编码是一小部分:仅在传输过程中保留结构。但一件作品本身并不是防御。许多开发人员将编码与清理混为一谈,因为两者都涉及替换字符,但在整个开发过程中服务于完全不同的重要工作。

端到端测试有效负载,以了解整个过程中编码和转义真正重要的地方。将 %3Cimg%20src%3Dx%20onerror%3Dalert%281%29%3E 粘贴到 URL 解码器中,并观察它变成看起来像标记的字符串。然后将结果粘贴到 HTML 实体转义器中,看看如何变成安全文本。两个工具使图层清晰可见。

要点:对 URL 进行编码,对输出进行转义 — URL 编码器和解码器以及 HTML 实体转义器如何在一个产品中并排放置以完成两项不同的工作

要点是,编码和转义始终是不同层的独立关注点。 URL 编码仅保护传输的结构。输出转义可以保护渲染的内容。正确编码的值在到达 HTML 时仍需要输出转义。正确转义的字符串如果不放入 URL,则永远不需要 URL 编码。

真正在右层应用右防御。不要依赖 URL 编码来阻止 XSS 攻击。不要依赖 HTML 转义来保留 URL 结构。了解您的数据流并在每个步骤中应用适当的转换。 URL 编码器可帮助您了解编码的作用;然后使用 HTML 实体转义器进行输出步骤。