ASP.NET请求验证绕过
2017年10月14日
…以及为什么你应该报告这个漏洞(也许)。
本文讨论的是.NET请求验证漏洞,如微软文档所述。虽然这不是新问题,但我在2017年仍发现许多.NET网站存在此问题。
请求验证机制剖析
请求验证是ASP.NET的输入过滤器,旨在防范XSS攻击。但微软官方声明该机制并不安全:
即使启用了请求验证,在显示用户输入内容前仍应进行HTML编码
这种设计存在逻辑矛盾:既然提供了XSS防护功能,为何还需要开发者手动编码?
技术缺陷实例
.NET控件默认不会自动HTML编码输出。例如以下代码会直接输出未编码内容:
|
|
.NET 4引入的<%:
语法实现了自动编码,但本应从一开始就内置此功能。
漏洞利用细节
正常情况下,请求验证会拦截包含HTML标签的请求,例如example.com/?foo=<b>
会触发"A potentially dangerous Request.QueryString"错误。
但特殊标签<%tag
可绕过验证,该标签仅在IE9中生效(需要标准模式或quirks模式)。攻击示例:
|
|
quirks模式下可利用CSS向量实现无交互触发:
|
|
渗透测试建议
当满足以下条件时应报告该漏洞:
- 能在IE9中证明JS执行(存储型/反射型)
- 企业环境因兼容性锁定IE9版本
- 证明应用缺乏输出编码机制
开发者修复方案
微软的根本错误在于将XSS视为输入问题而非输出问题。正确做法应包括:
- 禁用请求验证
- 全面实施HTML输出编码
- 避免直接输出到JS上下文
- 通过服务端验证限制非字母数字字符输入
请求验证还会导致功能异常,例如触发HTTP 500错误。更合理的做法是提供友好的客户端验证提示。
特别警示:自动化流程中若包含特殊字符可能导致意外中断