zoukankan      html  css  js  c++  java
  • 六、防止JavaScript注入攻击

    这篇文章主要介绍在ASP.NET MVC应用程序中如何防止JavaScript注入攻击。这篇文章讨论了两种防止JavaScript攻击的方法:
    显示数据的时候,通过使用Encoding来防止攻击
    接收到数据的时候,通过使用Encoding防止攻

    一、什么是JavaScript注入攻击(原创:灰灰虫的家 http://hi.baidu.com/grayworm
    在我们接收用户输入或在页面显示用户输入的数据时,我们的网站默认是向JavaScript注入攻击敞开了大门。让我们看看我们的Web应用程序如何被JavaScript攻击。
    假设我们创建了一个用户反馈的网站,用户可以访问该网站并填写产品使用的反馈信息。当用户填写完反馈信息后,程序会把用户的反馈信息显示在页面上。


    《图1 》
    用户反馈网站的控制器代码如下所示,其中包含两个动作Index()和Create()
    Listing 1 – HomeController.cs
    using System;
    using System.Web.Mvc;
    using CustomerFeedback.Models;
    namespace CustomerFeedback.Controllers
    {     
    [HandleError]     
    public class HomeController : Controller     
    {          
      private FeedbackDataContext db = new FeedbackDataContext();          
       public ActionResult Index()          
       {               
        return View(db.Feedbacks);          
       }          
       public ActionResult Create(string message)          
       {               
        // Add feedback               
        var newFeedback = new Feedback();               
        newFeedback.Message = message;               
        newFeedback.EntryDate = DateTime.Now;               
        db.Feedbacks.InsertOnSubmit(newFeedback);               
        db.SubmitChanges();               
        // Redirect               
       return RedirectToAction("Index");          
       }     
    }
    }
    Index()方法用来向视图传递显示数据的,这个方法检索表中所有的用户反馈信息,并传递给页面显示。
    Create()创建一个新的用户返回,并把它加到数据库中。用户在表单中输入的数据会以message参数被传递到Create()方法中。我们通过调用DataContext.SubmitChanges()方法把页面返回数据送到数据库中去。最后调用Index()动作,显示所有的用户反馈数据。

    Index视图代码如下
    Listing 2 – Index.aspx
    <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="CustomerFeedback.Views.Home.Index"%>
    <%@ Import Namespace="CustomerFeedback.Models" %>
    <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">     
    <h1>Customer Feedback</h1>     
    <p>Please use the following form to enter feedback about our product.</p>     
    <form method="post" action="/Home/Create">          
       <label for="message">Message:</label>          
       <br />          
       <textarea name="message" cols="50" rows="2"></textarea>          
       <br /><br />          
       <input type="submit" value="Submit Feedback" />     
    </form>     
    <% foreach (Feedback feedback in ViewData.Model)      {%>          
    <p>          
    <%=feedback.EntryDate.ToShortTimeString()%>--<%=feedback.Message%>          
    </p>     
    <% }%>
    </asp:Content>
    Index视图代码可以分成两部分来看待,上面的部分是用户输入的表单,下面的部分是foreach…loop循环,迭代所有的用户返馈信息,显示EntryDate和Message两个字段的信息。
    用户返馈网站很简单,但这个网站很容易被JavaScript攻击。
    如果用户输入的反馈内容是
    <script>alert(“Boo!”)</script>
    那这段文本在显示的时候会在页面上弹出一个消息框,以后任何人在访问这个网站的时候,在显示用户的反馈信息时都会弹出这个对话框。


    《图2》
    可能你对上面的JavaScript注入感觉没什么大不了的,好像它只能对我们的界面显示产生影响,它并不会给我们的网站的安全性还来真正可怕的影响。不幸的是,一个黑客足可以使用JavaScript攻击来给你的网站带来可怕的事情。它可以使用JavaScript注入执行Cross-Site Scripting攻击。Cross-Site Scripting攻击就是盗窃用来的机密信息并发送到别的网站上去。比如:黑客可以使用JavaScript注入攻击从客户机的Cookie中盗取敏感信息(密码、信用卡号、社保账号等),或者把其它用户表单中输入的机密数据发送到其它网站上去。

    二、解决方法一:在视图中使用Html.Encode显示数据(原创:灰灰虫的家 http://hi.baidu.com/grayworm
    防止JavaScript注入攻击的一个简单方法就是当显示用户输入的数据时,使用Html.Encode()方法把数据库中的数据编码显示。我们修改后的Index视图代码如下:
    Listing 3 – Index.aspx (HTML Encoded)
    <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="CustomerFeedback.Views.Home.Index"%>
    <%@ Import Namespace="CustomerFeedback.Models" %>
    <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">     
    <h1>Customer Feedback</h1>     
    <p>Please use the following form to enter feedback about our product. </p>     
    <form method="post" action="/Home/Create">          
       <label for="message">Message:</label>          
       <br />          
       <textarea name="message" cols="50" rows="2"></textarea>          
       <br /><br />          
       <input type="submit" value="Submit Feedback" />     
    </form>     
    <% foreach (Feedback feedback in ViewData.Model)      {%>          
    <p>          
    <%=feedback.EntryDate.ToShortTimeString()%>--<%=Html.Encode(feedback.Message)%>          
    </p>     
    <% }%>
    </asp:Content>
    我们注意到,在上面的代码中,我们把feedback.Message信息使用Html.Encode()方法进行了编码。
    <%=Html.Encode(feedback.Message)%>
    HTML Encode的意思就是,把一些危险的字符如<和>替换为&lt;和&gt;。
    所以当<script>alert("Boo!")</script>被Encode后,就会变为&lt;script&gt;alert(&quot;Boo!&quot;)&lt;/script&gt;。被编码后的字符串就不再是一个可执行的JavaScript代码了,它会正常显示在页面上。如下图所示


    《图3》
    上面的代码中我们只对feedback.Message进行了编码,而feedback.EntryDate没有进行编码。因为feedback.EntryDate是控制器生成的,不会有危险性,而feedback.Message是用户输入的,所以为了安全其见我们需要对其进行编码

    三、解决方法二:在控制器中对HTML数据进行编码(原创:灰灰虫的家 http://hi.baidu.com/grayworm
    除了在显示的时候对用户反馈的信息进行编码显示,我们还可以在控制器接收到用户提交的数据后进行编码,然后把编码后的数据送到数据库中
    下面的代码,是我们在控制器中对用户输入的数据进行编码
    Listing 4 – HomeController.cs (HTML Encoded)
    using System;
    using System.Web.Mvc;
    using CustomerFeedback.Models;
    namespace CustomerFeedback.Controllers
    {     
    [HandleError]     
    public class HomeController : Controller     
    {          
       private FeedbackDataContext db = new FeedbackDataContext();          
       public ActionResult Index()          
       {               
        return View(db.Feedbacks);          
       }          
       public ActionResult Create(string message)          
       {               
        // Add feedback               
        var newFeedback = new Feedback();               
       newFeedback.Message = Server.HtmlEncode(message);               
        newFeedback.EntryDate = DateTime.Now;               
        db.Feedbacks.InsertOnSubmit(newFeedback);               
        db.SubmitChanges();               
        // Redirect               
        return RedirectToAction("Index");          
       }     
    }
    }
    从上面的代码中我们看出,Create()动作在向数据库插入数据之前,对用户输入的数据进行编码。当在界面中显示数据库数据的时候,用户的输入已经被编码了,就不会造成危险。
    一般我们更推荐上面讨论的第一种解决方案,因为第二种方案会在数据库产生编码后的HTML标记,即会产生一些古怪难以理解的数据,这些数据在WEB页面中显示会变得正常,但在WinForms应用程序中显示时会搞成一团糟。

    总结
    这篇文章主要讨论了JavaScript攻击,并提出在ASP.NET MVC应用程序中两种解决方案:
    在显示数据的时候,通过使用Encoding来防止攻击
    在接收到数据的时候,通过使用Encoding防止攻

  • 相关阅读:
    TextBox类的成员
    【VB.Net】字节数与字符数的取得
    限制文本框的输入类型
    【转】FxCop 设计规则
    【Spread Sheet 应用(三)】Enter移向下一个单元格
    【ASP.NET】打开关闭新窗体
    常用字符对应ASCII码值
    初识CodeSmith分享两个模板
    【VB.NET】自定义控件(一)属性说明
    LeetCode: Length of Last Word
  • 原文地址:https://www.cnblogs.com/zxktxj/p/2461518.html
Copyright © 2011-2022 走看看