规范化和输出编码

信息安全 应用安全 owasp 验证 编码 混淆
2021-09-04 21:39:05

我正在阅读 OWASP 的安全编码实践清单,在他们的“输入验证”部分下,他们有一个项目如下:

<>"'%()&+\\'\"如果必须允许任何具有潜在危险的字符 ( ) 作为输入,请确保实施额外的控制,例如输出编码。利用规范化来解决双重编码或其他形式的混淆攻击。

  • 什么是“输出编码”,有人可以提供一个验证例程如何使用它的具体示例吗?
  • 什么是“双重编码”,为什么是“混淆攻击”?
  • 什么是“规范化”,为什么它会阻止双重编码?

对于第三个,我发现OWASP 提供的规范化定义相当模糊:将各种数据编码简化为单一、简单的形式。但是这个定义并不能真正帮助我理解他们在说什么。

我精通 Java 和 Python,但可以使用任何语言的示例。我只是想形象化他们在这里谈论的内容,并且很难看到“树林中的森林”。提前致谢!

2个回答
  • 什么是“输出编码”,有人可以提供一个验证例程如何使用它的具体示例吗?

输出编码意味着数据被适当地编码为它被放置的上下文。例如,假设您想动态显示来自不受信任来源Your name is:<b>Foo bar</b> 的名称:如果名称包含 html 字符,您希望对这些字符进行编码,因此结果是<b>Foo &lt;i&gt Bar</b>而不是<b>Foo <i> Bar</b>.

因此,转换<&lt;html 编码的一个示例。但是,如果上下文是 html 属性,您可能还必须对空格字符进行编码,因为属性可能不带引号,因此空格可能会破坏属性并且输入可以创建新属性: <input value=data>被攻击: <input value=data onclick=javascript:alert(1)/>

  • 什么是“双重编码”,为什么是“混淆攻击”?

当您在 URL 中键入某些字符时,这些字符将变为 URL 编码(通常,但并非总是在 IE 中):

  1. 未编码参数: test<script>alert(1)</script>
  2. URL 编码参数: test%3Cscript%3Ealert%281%29%3C%2fscript%3E
  3. 双编码参数: test%253Cscript%253Ealert%25281%2529%253C%252fscript%253E

根据对输入参数的处理,双重编码可能会通过一些过滤器/验证器并最终破坏它们被回显的上下文(从而导致 XSS)。

  • 什么是“规范化”,为什么它会阻止双重编码?

规范化是以最简单的形式编写某事物的行为,因此某事物的规范形式是编写它的“最简单”形式。在这种情况下进行规范化,这意味着取消编码数据,直到它不再改变。

三重编码<的符号经过以下转换:

  1. %25253C
  2. %253C
  3. %3C
  4. <

另一个例子是,如果输入被编写为例如八进制转义、过长的 UTF 序列和深奥的编码,例如 UTF-7。为了消除歧义,规范化将这些转换为公共基础。

我认为描述规范化的最佳方式是记住它源于canon,意思是真实的写作。他们正在谈论的是获取不受信任的数据并将其格式化为明确的表示形式,这样它就不会被任何软件进程歪曲。

第一步是获取您的输入并将其存储在某个地方。您的输入可能被编码为 ASCII、UTF-8、UTF-16 或任何数量的其他编码方案。软件必须检测到这一点,并以单一格式适当地转换和存储数据。它现在是单一明确的格式,因此在这样解释时已知是正确的,即它是canon这允许以后输出数据时绝对确定。

例如,如果我插入'; DROP TABLE users; --一个表单,如果应用程序编写得不好,它可能会导致 SQL 注入。但是,通过规范化,数据只是 data,不可能表示为 SQL 查询的一部分。实际上,SQL 的规范化形式是参数化查询。此外,必须采取措施将文本编码转换为单一已知类型,以便仅存储有效的代码点。如果不这样做,代码点可能会被误解为不同的字符。

可以给出一个类似的例子来输出到 HTML。如果数据库包含<script>alert('xss!');</script>,那么天真的应用程序可能会直接将其写入页面并引入安全问题。但是,通过输出编码形式的适当规范化,我们会得到&lt;script&gt;alert('xss!');&lt;/script&gt;,浏览器不会误解。

双重编码是用来欺骗某些解析器的技巧。攻击者识别您正在使用的编码,然后以这种格式对他们的数据进行预编码。解析器错误地将数据假定为canon,并照此处理。结果是数据处理不当,从而发生了漏洞利用。这是一种混淆攻击,因为攻击者正在混淆漏洞利用数据,这样编码器就看不到坏字符。