- 什么是“输出编码”,有人可以提供一个验证例程如何使用它的具体示例吗?
输出编码意味着数据被适当地编码为它被放置的上下文。例如,假设您想动态显示来自不受信任来源Your name is:<b>Foo bar</b>
的名称:如果名称包含 html 字符,您希望对这些字符进行编码,因此结果是<b>Foo <i> Bar</b>而不是<b>Foo <i> Bar</b>.
因此,转换<为<html 编码的一个示例。但是,如果上下文是 html 属性,您可能还必须对空格字符进行编码,因为属性可能不带引号,因此空格可能会破坏属性并且输入可以创建新属性:
<input value=data>被攻击:
<input value=data onclick=javascript:alert(1)/>
当您在 URL 中键入某些字符时,这些字符将变为 URL 编码(通常,但并非总是在 IE 中):
- 未编码参数:
test<script>alert(1)</script>
- URL 编码参数:
test%3Cscript%3Ealert%281%29%3C%2fscript%3E
- 双编码参数:
test%253Cscript%253Ealert%25281%2529%253C%252fscript%253E
根据对输入参数的处理,双重编码可能会通过一些过滤器/验证器并最终破坏它们被回显的上下文(从而导致 XSS)。
规范化是以最简单的形式编写某事物的行为,因此某事物的规范形式是编写它的“最简单”形式。在这种情况下进行规范化,这意味着取消编码数据,直到它不再改变。
三重编码<的符号经过以下转换:
%25253C
%253C
%3C
<
另一个例子是,如果输入被编写为例如八进制转义、过长的 UTF 序列和深奥的编码,例如 UTF-7。为了消除歧义,规范化将这些转换为公共基础。