Предотвращение атак, осуществляемых путем внедрения кода JavaScript (VB)
Стивен Уолтер (Stephen Walther)
Предотвращение атак путем внедрения кода JavaScript и межсайтовых сценариев. В этом руководстве Стивен Уолтер объясняет, как можно легко победить эти типы атак, кодируя содержимое в ФОРМАТЕ HTML.
Цель этого руководства — объяснить, как можно предотвратить атаки путем внедрения кода JavaScript в приложениях ASP.NET MVC. В этом руководстве рассматриваются два подхода к защите веб-сайта от атак путем внедрения кода JavaScript. Вы узнаете, как предотвратить атаки путем внедрения кода JavaScript путем кодирования отображаемых данных. Вы также узнаете, как предотвратить атаки путем внедрения кода JavaScript путем кодирования принимаемых данных.
Что такое атака путем внедрения кода JavaScript?
Всякий раз, когда вы принимаете введенные пользователем данные и повторно воспроизводите введенные пользователем данные, вы открываете свой веб-сайт для атак путем внедрения кода JavaScript. Давайте рассмотрим конкретное приложение, открытое для атак путем внедрения кода JavaScript.
Представьте, что вы создали веб-сайт отзывов клиентов (см. рис. 1). Клиенты могут посетить веб-сайт и ввести отзывы о своем опыте использования ваших продуктов. Когда клиент отправляет свой отзыв, он повторно отображается на странице отзывов.
Рис. 01. Веб-сайт отзывов клиентов (щелкните для просмотра полноразмерного изображения)
На веб-сайте отзывов клиентов используется в листинге controller
1. Содержит controller
два действия с именами Index()
и Create()
.
Листинг 1 — HomeController.vb
Public Class HomeController
Inherits System.Web.Mvc.Controller
Private db As New FeedbackDataContext()
Function Index()
Return View(db.Feedbacks)
End Function
Function Create(ByVal message As String)
' Add feedback
Dim newFeedback As New Feedback()
newFeedback.Message = Server.HtmlEncode(message)
newFeedback.EntryDate = DateTime.Now
db.Feedbacks.InsertOnSubmit(newFeedback)
db.SubmitChanges()
' Redirect
Return RedirectToAction("Index")
End Function
End Class
Метод Index()
отображает Index
представление. Этот метод передает все предыдущие отзывы клиентов в Index
представление путем получения обратной связи из базы данных (с помощью запроса LINQ to SQL).
Метод Create()
создает новый элемент Feedback и добавляет его в базу данных. Сообщение, введенное клиентом в форме, передается методу Create()
в параметре message. Создается элемент "Отзыв", и сообщение назначается свойству элемента Message
Feedback. Элемент Feedback отправляется в базу данных с DataContext.SubmitChanges()
помощью вызова метода . Наконец, посетитель перенаправляется обратно в Index
представление, где отображаются все отзывы.
Представление Index
содержится в листинге 2.
Листинг 2 — Index.aspx
<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="false" CodeBehind="Index.aspx.vb" Inherits="CustomerFeedback.Index"%>
<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>
<% For Each feedback As CustomerFeedback.Feedback In ViewData.Model%>
<p>
<%=feedback.EntryDate.ToShortTimeString()%>
--
<%=feedback.Message%>
</p>
<% Next %>
</asp:Content>
Представление Index
состоит из двух разделов. В верхней части содержится фактическая форма обратной связи с клиентами. В нижнем разделе содержится элемент For.. Каждый цикл, который перебирает все предыдущие элементы отзывов клиентов и отображает свойства EntryDate и Message для каждого элемента обратной связи.
Веб-сайт отзывов клиентов — это простой веб-сайт. К сожалению, веб-сайт открыт для атак путем внедрения кода JavaScript.
Представьте, что вы вводите следующий текст в форму обратной связи клиента:
<script>alert("Boo!")</script>
Этот текст представляет скрипт JavaScript, который отображает окно оповещения. После того как кто-то отправит этот скрипт в форму обратной связи, появится сообщение Boo!будет отображаться каждый раз, когда кто-либо заходит на веб-сайт отзывов клиентов в будущем (см. рис. 2).
Рис. 02. Внедрение Кода JavaScript (щелкните для просмотра полноразмерного изображения)
Теперь ваш первоначальный ответ на атаки путем внедрения кода JavaScript может быть апатией. Вы можете подумать, что атаки путем внедрения кода JavaScript — это просто тип атаки дефайсмента . Вы можете поверить, что никто не может сделать ничего действительно плохого, совершив атаку путем внедрения кода JavaScript.
К сожалению, хакер может сделать некоторые действительно, действительно плохие вещи, внедряя JavaScript на веб-сайт. Вы можете использовать атаку путем внедрения кода JavaScript для выполнения атаки межсайтовых сценариев (XSS). При атаке меж site-scripting вы похищаете конфиденциальные сведения о пользователях и отправляете их на другой веб-сайт.
Например, злоумышленник может использовать атаку путем внедрения кода JavaScript для кражи значений файлов cookie браузера у других пользователей. Если конфиденциальная информация, например пароли, номера кредитов карта или номера социального страхования, хранится в файлах cookie браузера, злоумышленник может использовать атаку путем внедрения Кода JavaScript, чтобы украсть эту информацию. Или, если пользователь вводит конфиденциальную информацию в поле формы, содержащееся на странице, которая была скомпрометирована атакой На JavaScript, злоумышленник может использовать внедренный Код JavaScript, чтобы захватить данные формы и отправить их на другой веб-сайт.
Пожалуйста, бойтесь. Серьезно относитесь к атакам путем внедрения кода JavaScript и защитите конфиденциальную информацию пользователя. В следующих двух разделах мы обсудим два метода, которые можно использовать для защиты ASP.NET приложений MVC от атак путем внедрения кода JavaScript.
Подход 1. Кодирование HTML в представлении
Одним из простых способов предотвращения атак путем внедрения кода JavaScript является кодирование html любых данных, введенных пользователями веб-сайта при повторном воспроизведении данных в представлении. Обновленное Index
представление в листинге 3 соответствует этому подходу.
Листинг 3 . Index.aspx
(в кодировке HTML)
<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="false" CodeBehind="Index.aspx.vb" Inherits="CustomerFeedback.Index"%>
<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>
<% For Each feedback As CustomerFeedback.Feedback In ViewData.Model%>
<p>
<%=feedback.EntryDate.ToShortTimeString()%>
--
<%=Html.Encode(feedback.Message)%>
</p>
<% Next %>
</asp:Content>
Обратите внимание, что значение feedback.Message
закодировано в ФОРМАТЕ HTML перед отображением значения с помощью следующего кода:
<%=Html.Encode(feedback.Message)%>
Что означает кодирование строки в ФОРМАТЕ HTML? При кодировании строки в HTML опасные символы, такие как <
и >
, заменяются ссылками на сущности HTML, такие как <
и >
. Поэтому при кодировании строки <script>alert("Boo!")</script>
в формате HTML она преобразуется в <script>alert("Boo!")</script>
. Закодированная строка больше не выполняется как скрипт JavaScript при интерпретации браузером. Вместо этого вы получите безвредную страницу на рис. 3.
Рис. 03. Неудачная атака JavaScript (щелкните, чтобы просмотреть полноразмерное изображение)
Обратите внимание, что в представлении Index
в листинге 3 кодируется только значение feedback.Message
. Значение feedback.EntryDate
не закодировано. Вам нужно только кодировать данные, введенные пользователем. Так как значение EntryDate было создано в контроллере, вам не нужно кодировать это значение в ФОРМАТЕ HTML.
Подход 2. Кодирование HTML в контроллере
Вместо кодирования данных HTML при отображении данных в представлении можно кодировать данные в ФОРМАТЕ HTML непосредственно перед отправкой данных в базу данных. Второй подход используется в случае с в листинге controller
4.
Листинг 4 . HomeController.cs
(в кодировке HTML)
Public Class HomeController
Inherits System.Web.Mvc.Controller
Private db As New FeedbackDataContext()
Function Index()
Return View(db.Feedbacks)
End Function
Function Create(ByVal message As String)
' Add feedback
Dim newFeedback As New Feedback()
newFeedback.Message = Server.HtmlEncode(message)
newFeedback.EntryDate = DateTime.Now
db.Feedbacks.InsertOnSubmit(newFeedback)
db.SubmitChanges()
' Redirect
Return RedirectToAction("Index")
End Function
End Class
Обратите внимание, что перед отправкой значения в базу данных в действии значение Message закодировано в Create()
ФОРМАТЕ HTML. При повторном воспроизведении сообщения в представлении оно закодировано в ФОРМАТЕ HTML, а любой Код JavaScript, внедренный в сообщение, не выполняется.
Как правило, следует использовать первый подход, рассматриваемый в этом руководстве, а не этот второй подход. Проблема второго подхода заключается в том, что в базе данных в конечном итоге будут данные в кодировке HTML. Иными словами, данные вашей базы данных загрязняются смешными символами.
Почему это плохо? Если вам когда-либо потребуется отобразить данные базы данных не на веб-странице, у вас возникнут проблемы. Например, вы больше не можете легко отображать данные в приложении Windows Forms.
Итоги
Цель этого руководства — напугать вас перспективой атаки путем внедрения кода JavaScript. В этом руководстве рассматриваются два подхода к защите приложений ASP.NET MVC от атак путем внедрения кода JavaScript: вы можете кодировать данные, отправленные пользователем, в представлении в ФОРМАТЕ HTML, или кодировать данные, отправленные пользователем в контроллере.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по