ASP.NET请求验证绕过技术解析

本文深入分析ASP.NET请求验证机制的安全缺陷,探讨如何利用<%tag在IE9中绕过验证实现XSS攻击,并强调输出编码才是XSS防护的核心措施。

ASP.NET请求验证绕过

2017年10月14日

…以及为何应该报告此漏洞(或许)。

本文针对.NET请求验证漏洞进行探讨,如此处所述。需注意这并非新漏洞,但2017年我仍在.NET网站中普遍发现该问题。

请求验证是ASP.NET的输入过滤器,旨在防护XSS攻击,尽管微软自身声明其并不安全:

即使使用请求验证,在显示用户输入内容前也应进行HTML编码。

这显得有些荒谬——既然为框架用户提供了缓解XSS的功能,为何还要用户自行实施XSS防护措施?微软本应确保所有.NET控件正确输出HTML编码内容。例如以下代码中,除非开发者手动输出编码,否则将引发XSS:

1
2
3
4
5
<asp:Repeater ID="Repeater2" runat="server">
  <ItemTemplate>
    <%# Eval("YourField") %>
  </ItemTemplate>
</asp:Repeater>

.NET 4引入的<%:语法实现了自动HTML编码,但本应从最初就具备该功能。

验证机制与绕过原理

通常ASP.NET请求验证会拦截包含标签的HTTP请求,例如:
example.com/?foo=<b> 会触发"检测到客户端存在潜在危险的QueryString值"错误,并显示黄屏死机界面。

此机制旨在防止用户输入<script>标签或尝试<svg onload="alert(1)" />等向量。但漏洞在于允许<%tag——这是仅适用于IE9的特殊标签(需标准模式,但quirks模式需用户交互如鼠标悬停)。示例页面需包含以下声明:

1
2
<!doctype html>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">

验证PoC代码:

1
2
3
4
5
6
7
8
9
<!doctype html>
<html>
<head>
	<meta http-equiv="X-UA-Compatible" content="IE=Edge">
</head>
<body>
	<%tag onmouseover="alert('markitzeroday.com')">移动鼠标至此
</body>
</html>

在quirks模式下可使用CSS向量(无需文档类型声明):

1
2
3
4
5
6
<html>
<head></head>
<body>
	<%tag style="xss:expression(alert('markitzeroday.com'))">无需鼠标悬停
</body>
</html>

报告价值与防护建议

即使仅影响IE9,仍需报告此漏洞,因为:

  1. 某些组织因兼容性仍使用旧版IE
  2. 证明输出编码机制缺失,暗示应用可能存在其他漏洞

请求验证会破坏功能完整性——类似HTTP 500的响应会导致应用中断。微软的根本错误在于将XSS视为输入问题而非输出问题。核心防护措施应是输出编码(如将<转换为&lt;),而非依赖输入验证。

渗透测试建议
若在IE9中验证JavaScript执行(存储型或反射型),应提交报告。

开发建议
关闭请求验证,全面实施HTML编码(避免直接输出到JavaScript),必要时通过服务端验证限制非字母数字字符输入。

本文仅作技术研究,请合法合规使用相关知识。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计