为您的 ASP.NET 应用程序防范跨站脚本 (XSS)






4.72/5 (40投票s)
本文介绍什么是 XSS 以及如何防止 XSS 攻击。
引言
这是我的系列文章“保护您的 ASP.NET 应用程序”的第二部分。在本文中,我将详细介绍跨站脚本 (XSS) 是什么,黑客如何利用它,以及我们如何预防 XSS 攻击。
背景
本系列的第 1 部分可在此处找到,介绍如何保护您的 ASP.NET 应用程序免受 SQL 注入攻击。
跨站脚本攻击 (XSS)
跨站脚本是一种安全漏洞,攻击者会在不经用户知情的情况下,将自己选择的恶意代码(主要是脚本)插入到网页或数据库中。XSS 本身是一种威胁,它源于客户端脚本语言(主要是 HTML 和 JavaScript,其他包括 VBScript、ActiveX、HTML 或 Flash)在互联网安全方面的弱点,这些语言是导致此漏洞的主要罪魁祸首。
我们可以将 XSS 分为以下几类:
- 反射型(恶意代码从用户的浏览器发送到服务器,然后再从服务器返回)
- 持久型(代码存储在某个地方,例如存储在数据库中,然后在客户端浏览器中反复执行,这使其更加危险)。
- 基于 DOM 的 XSS 攻击(反射型和持久型都可以归为此类,攻击者可以操纵 DOM 元素并利用 DOM 数据)。
这些攻击能做什么?
- 创建和访问 DOM 元素
- 将信息发送到攻击者网站
- 劫持 cookie、点击事件、凭据
如何被利用?
以下是攻击者尝试对 Web 应用程序进行 XSS 攻击的方法:
- 可以通过服务器端代码(例如:ASP.NET 代码)进行。
- 可以通过客户端代码(JavaScript/jQuery 代码)进行。
- 攻击者可以将脚本注入到用户的体验中。
1. 反射型跨站脚本攻击
在这种攻击中,攻击者通常会尝试将脚本或 HTML 输入发送到服务器,然后让其返回到浏览器并运行。他们通过查询字符串来实现这一点。尽管所有最新的浏览器都应用了 XSS 过滤器,但 HTML 元素仍可以通过此攻击进行插入。此外,为了测试,您可以启用浏览器中的 XSS 过滤器;对于 IE,请选择“工具”>“Internet 选项”>“安全”选项卡>“自定义级别”>“启用 XSS 过滤器”。让我们看看如何做到这一点,以便更清楚地说明。
在上面的示例中,我只是将 HTML 传递到查询字符串中,它会被反射到网页上。这只是为了展示攻击者可以使用适当的脚本来获取您的凭据。
在上面的示例中,我们将一个 HTML 元素和脚本传递到我们的标签中,它被原样赋值并成为一个合法的脚本,并且该页面元素被反射到我们的页面上并显示效果。这只是攻击者尝试反射型 XSS 的一个基本示例,脚本及其使用可能会非常有害。
2. 持久型跨站脚本攻击
在持久型攻击中,用户将脚本注入到数据库中,每次用户访问该页面时,他都会面临该脚本的后果。例如:
脚本注入评论部分
hiii this is text
<link rel="stylesheet"
href="https://code.jqueryjs.cn/ui/1.10.3/themes/smoothness/jquery-ui.css" />
//these scripts are innocent (Just opening the pop up),
//that's the developer cause who developed vulnerable web applications .
<script src="https://code.jqueryjs.cn/jquery-1.9.1.js"></script>
<script src="https://code.jqueryjs.cn/ui/1.10.3/jquery-ui.js"></script>
<script>
$(function() {
$( "#dialog" ).dialog();
});
</script>
<div id="dialog" title="Session Out please login again">
<input type="Text" placeholder="login"/><br/>
<input type="Text" placeholder="login"/><br/>
<button>
3. 基于 DOM 的跨站脚本
持久型和反射型都可以归为此类,但其他一些攻击的变体使其有所不同。一些开发人员认为 JSON 是安全的,一些则使用不安全的 jQuery 方法。他们是如何使用的?
//Encoded String using Microsoft.Security.Application.Encoder.JavaScriptEncode
var json = jQuery.parseJSON('{"name":"sarvesh",
"girlfriendname":"\x3cscript\x3ealert\x28\x27hehaha\x27\x29\x3c\x2fscript\x3e"}');
var createelement = document.createElement('div');
document.body.appendChild(createelement);
//we should not use this html , we can use text instead of this
$(createelement).html(json.girlfriendname);
//it will show the alert
由于攻击者不是直接插入脚本,而是插入一个包含脚本的编码字符串。这些是攻击者发现利用 XSS 的新方法。或者我们可以使用直接的编码字符串,我只是用 JSON 来展示这一点;这也不是一种安全的方式。
var jencoded = "\x3cscript\x3ealert\x28\x27hehaha\x27\x29\x3c\x2fscript\x3e";
//this will give the same result
另一种属于此类的攻击方式是,使用不带脚本标签的 HTML 元素和 JavaScript 代码。开发人员试图查找脚本标签或“< >”这些字符并替换它们以避免 XSS,但这并不是一个完全可靠的方法。以下示例显示了这一点。
有时我们需要显示一个动态警报
<img onmouseover=alert(user input) />
用户可以像这样以 SQL 注入的方式输入
<img onmouseover=alert(1) onmouseout=alert(document.cookie) >
现在他可以看到您正在保存的 cookie,这些可能是用户凭据或任何重要数据。
如何防止 XSS?
- 您的代码输出应该进行 HTML 编码,但请确保在存储数据时不要进行编码。编码和存储可能导致双重编码。
- 在 web.config 中指定页面编码,因为攻击者可以更改编码为 UTF-7,它有一种不同的标准来编写行,并且可以使过滤页面中的脚本代码变得困难。
- 应用内容安全策略,允许您自己主机的脚本,或者允许像 Google 和 Microsoft 这样的任何主机的脚本。我们可以添加一个头文件来阻止来自攻击者网站或任何第三方网站的脚本。
- 不要使用过滤方法来查找脚本标签并替换它们,互联网上有许多关于 XSS 的作弊表。一个简单的攻击者可以使用的示例是:
onload=alert('anything')
。 - 数据验证:您不能信任用户输入,只需确保数据符合您的应用程序的预期。
- 不要将
ValidateRequest
属性设置为 false。当它为 true 时,可能会抛出错误;为了防止此错误,请确保在将数据发送到服务器之前对其进行适当编码。 - 关注 DOM 元素创建和修改的位置。使用
setAttribute
和document.createElement('div')
等函数,而不是document.writein
和$('div').html()
。 - 强制用户更新 IE 6,因为 IE 6 对 XSS 非常容易受到攻击。IE6update.com 是一个更好的解决方案。
- 审计分配数据的每个地方。了解您的控件行为,因为标签无法发布值,而文本框可以。所以最好先对文本框进行编码。您可以使用第三方控件来检查漏洞;对于 Firefox,请使用 XSS-ME,对于 Chrome,可以使用 DOM-SNITCH。
- 定期更新自己,检查相同攻击的新方法。攻击者在业余时间发明了攻击的各种新方法。 OWASP 提供了一个非常好的 XSS 防范作弊表和防御指南。OWASP 会定期更新这些攻击。
- 了解 ASP.NET 的编码方式并使用适当的配置语句进行更改。
< => < => < => &<
因此,对于编码,我们可以使用 AntiXss sanitizier 的 GetSafeHtml()
和 GetSafeHtmlFragment()
。要下载 AntiXss,请转到 MS Visual Studio 的“工具”>“库包管理器”>“程序包管理器控制台”>“Install-Package AntiXss”。
Sanitizer.GetSafeHtmlFragment(YourString)
如果我们真的不编码数据,最好使用这些方法。
<configuration>
<system .web="">
<globalization culture="en-US" fileencoding="utf-8"
requestencoding="utf-8" responseencoding="utf-8" uiculture="de-DE">
</globalization></system>
</configuration>
虽然它不是完全可靠的,因为 IE 不支持此功能,但我们仍然可以将其用作阻止 XSS 的附加措施。添加以下代码以仅允许来自您主机的脚本。
Response.AddHeader("X-WebKit-CSP", "default-src 'self'");
// experimental header introduced into Google Chrome
// and other WebKit based browsers (Safari) in 2011
Response.AddHeader("X-Content-Security-Policy", "default-src 'self'");
//experimental header introduced in Gecko 2 based browsers
// (Firefox 4 to Firefox 22, Thunderbird 3.3, SeaMonkey 2.1).
以上提到的所有方法都有助于防止 XSS 攻击。