ASP.NET请求验证绕过
2017年10月14日
…以及为何应该报告此漏洞(或许)。
本文针对.NET请求验证漏洞进行探讨,如此处所述。需注意这并非新漏洞,但2017年我仍在.NET网站中普遍发现该问题。
请求验证是ASP.NET的输入过滤器,旨在防护XSS攻击,尽管微软自身声明其并不安全:
即使使用请求验证,在显示用户输入内容前也应进行HTML编码。
这显得有些荒谬——既然为框架用户提供了缓解XSS的功能,为何还要用户自行实施XSS防护措施?微软本应确保所有.NET控件正确输出HTML编码内容。例如以下代码中,除非开发者手动输出编码,否则将引发XSS:
|
|
.NET 4引入的<%:
语法实现了自动HTML编码,但本应从最初就具备该功能。
验证机制与绕过原理
通常ASP.NET请求验证会拦截包含标签的HTTP请求,例如:
example.com/?foo=<b>
会触发"检测到客户端存在潜在危险的QueryString值"错误,并显示黄屏死机界面。
此机制旨在防止用户输入<script>
标签或尝试<svg onload="alert(1)" />
等向量。但漏洞在于允许<%tag
——这是仅适用于IE9的特殊标签(需标准模式,但quirks模式需用户交互如鼠标悬停)。示例页面需包含以下声明:
|
|
验证PoC代码:
|
|
在quirks模式下可使用CSS向量(无需文档类型声明):
|
|
报告价值与防护建议
即使仅影响IE9,仍需报告此漏洞,因为:
- 某些组织因兼容性仍使用旧版IE
- 证明输出编码机制缺失,暗示应用可能存在其他漏洞
请求验证会破坏功能完整性——类似HTTP 500的响应会导致应用中断。微软的根本错误在于将XSS视为输入问题而非输出问题。核心防护措施应是输出编码(如将<
转换为<
),而非依赖输入验证。
渗透测试建议:
若在IE9中验证JavaScript执行(存储型或反射型),应提交报告。
开发建议:
关闭请求验证,全面实施HTML编码(避免直接输出到JavaScript),必要时通过服务端验证限制非字母数字字符输入。
本文仅作技术研究,请合法合规使用相关知识。