Sdílet prostřednictvím


Prevence útoků založených na injektáži JavaScriptu (C#)

Stephen Walther

Zabraňte útokům prostřednictvím injektáže JavaScriptu a skriptování mezi weby. V tomto kurzu Stephen Walther vysvětluje, jak můžete tyto typy útoků snadno porazit kódováním OBSAHU ve formátu HTML.

Cílem tohoto kurzu je vysvětlit, jak můžete zabránit útokům prostřednictvím injektáže JavaScriptu v aplikacích ASP.NET MVC. Tento kurz popisuje dva přístupy k obraně webu před útokem prostřednictvím injektáže JavaScriptu. Naučíte se, jak zabránit útokům prostřednictvím injektáže JavaScriptu kódováním zobrazených dat. Dozvíte se také, jak zabránit útokům prostřednictvím injektáže JavaScriptu kódováním dat, která přijímáte.

Co je útok prostřednictvím injektáže JavaScriptu?

Kdykoli přijmete vstup uživatele a znovu zobrazíte uživatelský vstup, otevřete web útokům prostřednictvím injektáže JavaScriptu. Pojďme se podívat na konkrétní aplikaci, která je otevřená útokům prostřednictvím injektáže JavaScriptu.

Představte si, že jste vytvořili web pro zpětnou vazbu od zákazníků (viz Obrázek 1). Zákazníci můžou navštívit tento web a zadat zpětnou vazbu o svých zkušenostech s používáním vašich produktů. Když zákazník odešle zpětnou vazbu, znovu se zobrazí na stránce zpětné vazby.

Web pro zpětnou vazbu od zákazníků

Obrázek 01: Web pro zpětnou vazbu od zákazníků (kliknutím zobrazíte obrázek v plné velikosti)

Web pro zpětnou vazbu od zákazníků používá controller v seznamu 1. Obsahuje controller dvě akce s názvem Index() a Create().

Výpis 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");
          }
     }
}

Metoda Index() zobrazí Index zobrazení. Tato metoda předá do zobrazení veškerou předchozí zpětnou vazbu Index od zákazníků načtením zpětné vazby z databáze (pomocí LINQ to SQL dotazu).

Metoda Create() vytvoří novou položku Zpětné vazby a přidá ji do databáze. Zpráva, kterou zákazník zadá ve formuláři, se předá Create() metodě v parametru message. Vytvoří se položka zpětné vazby a zpráva se přiřadí vlastnosti položky Zpětné vazby Message . Položka Zpětná vazba se odešle do databáze pomocí DataContext.SubmitChanges() volání metody . Nakonec se návštěvník přesměruje zpět do Index zobrazení, kde se zobrazí veškerá zpětná vazba.

Zobrazení Index je obsaženo ve výpisu 2.

Výpis 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>

Zobrazení Index má dvě části. Horní část obsahuje skutečný formulář pro zpětnou vazbu od zákazníků. Dolní část obsahuje for.. Každá smyčka prochází všechny předchozí položky zpětné vazby zákazníků a zobrazuje vlastnosti EntryDate a Message pro každou položku zpětné vazby.

Web pro zpětnou vazbu od zákazníků je jednoduchý web. Web je bohužel otevřený útokům prostřednictvím injektáže JavaScriptu.

Představte si, že do formuláře pro zpětnou vazbu od zákazníků zadáte následující text:

<script>alert("Boo!")</script>

Tento text představuje javascriptový skript, který zobrazí okno se zprávou upozornění. Jakmile někdo odešle tento skript do formuláře pro zpětnou vazbu, zpráva Boo!se zobrazí vždy, když někdo v budoucnu navštíví web pro zpětnou vazbu od zákazníků (viz Obrázek 2).

Injektáž JavaScriptu

Obrázek 02: Injektáž JavaScriptu (kliknutím zobrazíte obrázek v plné velikosti)

Vaše počáteční reakce na útoky prostřednictvím injektáže JavaScriptu může být apatie. Možná si myslíte, že útoky prostřednictvím injektáže JavaScriptu jsou jednoduše typem útoku na znechucení identity . Můžete se domnívat, že nikdo nemůže udělat nic skutečně zlého tím, že páchá útok prostřednictvím injektáže JavaScriptu.

Hacker bohužel může udělat opravdu špatné věci vložením JavaScriptu na web. Útok prostřednictvím injektáže JavaScriptu můžete použít k provedení útoku skriptování mezi weby (XSS). Při útoku skriptováním mezi weby ukradnete důvěrné informace o uživateli a odešlete je na jiný web.

Hacker může například pomocí útoku prostřednictvím injektáže JavaScriptu ukrást ostatním uživatelům hodnoty souborů cookie prohlížeče. Pokud jsou citlivé informace – například hesla, čísla platebních karet nebo čísla sociálního pojištění – uloženy v souborech cookie prohlížeče, může hacker tyto informace ukrást pomocí útoku prostřednictvím injektáže JavaScriptu. Nebo pokud uživatel zadá citlivé informace do pole formuláře obsaženého na stránce, která byla ohrožena útokem v JavaScriptu, hacker může použít vložený JavaScript k získání dat formuláře a jejich odeslání na jiný web.

Prosím, vyděste se. Vezměte útoky prostřednictvím injektáže JavaScriptu vážně a chraňte důvěrné informace uživatelů. V následujících dvou částech probereme dvě techniky, které můžete použít k ochraně aplikací ASP.NET MVC před útoky prostřednictvím injektáže JavaScriptu.

Přístup č. 1: Kódování HTML v zobrazení

Jednou ze snadných metod, jak zabránit útokům prostřednictvím injektáže JavaScriptu, je zakódovat html všechna data zadaná uživateli webu při opětovném zobrazení dat v zobrazení. Aktualizované Index zobrazení ve výpisu 3 se řídí tímto přístupem.

Výpis 3 – Index.aspx (kódovaný HTML)

<%@ 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>

Všimněte si, že hodnota feedback.Message má kódování HTML před zobrazením hodnoty s následujícím kódem:

<%=Html.Encode(feedback.Message)%>

Co znamená kódování řetězce ve formátu HTML? Když kódujete řetězec ve formátu HTML, nebezpečné znaky jako < a > se nahradí odkazy na entity HTML, jako &lt; jsou a &gt;. Když je řetězec <script>alert("Boo!")</script> zakódovaný ve formátu HTML, převede se na &lt;script&gt;alert(&quot;Boo!&quot;)&lt;/script&gt;. Kódovaný řetězec se už při interpretaci prohlížečem nespustí jako javascriptový skript. Místo toho získáte neškodnou stránku na obrázku 3.

Poražený javascriptový útok

Obrázek 03: Poražený javascriptový útok (kliknutím zobrazíte obrázek v plné velikosti)

Všimněte si, že v Index zobrazení ve výpisu 3 je zakódovaná pouze hodnota feedback.Message . Hodnota feedback.EntryDate není kódována. Stačí jenom zakódovat data zadaná uživatelem. Vzhledem k tomu, že hodnota EntryDate byla vygenerována v kontroleru, nemusíte tuto hodnotu kódovat html.

Přístup č. 2: Kódování HTML v kontroleru

Místo dat kódování HTML při zobrazení dat v zobrazení můžete data kódovat ve formátu HTML těsně před odesláním dat do databáze. Tento druhý přístup se používá v případě ve výpisu controller 4.

Výpis 4 – HomeController.cs (kódovaný HTML)

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");
          }
     }
}

Všimněte si, že hodnota Message má kódování HTML před odesláním hodnoty do databáze v rámci Create() akce. Při opětovném zobrazení zprávy v zobrazení je zpráva zakódovaná ve formátu HTML a žádný JavaScript vložený do zprávy se nespustí.

Obvykle byste měli upřednostňovat první přístup probíraný v tomto kurzu před tímto druhým přístupem. Problém s tímto druhým přístupem spočívá v tom, že v databázi máte data zakódovaná ve formátu HTML. Jinými slovy data databáze jsou zašpiněná vtipnými znaky.

Proč je to špatné? Pokud byste někdy potřebovali data databáze zobrazit na jiném místě než na webové stránce, budete mít problémy. Už například nemůžete snadno zobrazit data v model Windows Forms aplikaci.

Souhrn

Účelem tohoto kurzu bylo vyděsit vás před potenciálním útokem prostřednictvím injektáže JavaScriptu. Tento kurz probíral dva přístupy k ochraně aplikací ASP.NET MVC před útoky prostřednictvím injektáže JavaScriptu: data odeslaná uživatelem můžete buď zakódovat ve formátu HTML v zobrazení, nebo můžete kódovat data odeslaná uživatelem v kontroleru.