Книга: ASP.NET MVC Framework
ValidateInputAttribute
ValidateInputAttribute
Одной из самых уязвимых частей любого веб-сайта является пользовательский ввод. Представьте ситуацию, когда после ввода пользовательских данных, они сразу же становятся видны другим пользователям. Тогда, если не существует никакой фильтрации таких данных, злоумышленник может ввести вместо данных опасный код на JavaScript, который повредит любому, кто попытается получить доступ к вашему сайту. Для предотвращения ввода таких данных в механизм ASP.NET MVC встроена защита, которая проверяет любой запрос на наличие потенциально опасных значений параметров запроса.
По умолчанию этот механизм включен для всех запросов, и ничего дополнительного делать не нужно. Но существуют случаи, когда все же требуется получить введенные пользователем данные, даже если они могут быть опасными. Например, если вы разрабатываете редактор для записей блога, то вам, возможно, будет необходимо предоставить пользователю возможность вводить HTML-разметку вместе с содержимым записи блога. Если оставить механизм защиты ASP.NET MVC включенным, то любой запрос, параметр которого содержит теги, будет вызывать исключительную ситуацию.
ASP.NET MVC предлагает разработчику гибкий механизм управления проверкой параметров запроса. Для такого управления существует атрибут ValidateInputAttribute
. Для демонстрации действия этого атрибута добавим в нашу форму редактирования параметров Select.aspx
возможность редактирования поля Comment
, которое будет содержать любой текст, в том числе и с HTML-разметкой. Данное поле будет выводиться вместе с отображаемым именем пользователя, играя роль сообщения для пользователя.
Изменим форму ввода, добавив следующий фрагмент кода:
<p>
<label for="comment">Комментарий</label>
<%=Html.TextArea("comment", user.Comment) %>
</p>
Соответственно изменим определение действия Update
контроллера AdminController:
[AcceptVerbs(HttpVerbs.Post)]
[Authorize(Users = "Admin")]
[ValidateAntiForgeryToken]
public ActionResult Update(Guid? userId, string email,
string comment, bool isApproved, bool isLockedOut)
{
if (!userId.HasValue)
throw new HttpException(404, "Пользователь не найден");
MembershipProvider mp = Membership.Provider;
MembershipUser user = mp.GetUser(userId, false);
user.Email = email;
user.Comment = comment;
user.IsApproved = isApproved;
if (user.IsLockedOut && !isLockedOut) user.UnlockUser();
mp.UpdateUser(user);
return RedirectToAction("Index");
}
Для того чтобы пользователь видел сообщение, модифицируем частичное представление LogOnUserControl.ascx
так, как показано в листинге 4.4.
Листинг 4.4. Представление LogOnUserControl.ascx
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%
if (Request.IsAuthenticated) {
%>
Welcome <b><%= Html.Encode(Page.User.Identity.Name) %></b>!
[ <%= Html.ActionLink("Log Off", "LogOff", "Account") %> ]
<p><%= Membership.GetUser(Page.User.Identity.Name).Comment %></p>
}
else {
%>
[ <%= Html.ActionLink("Log On", "LogOn", "Account") %> ]
<%
}
%>
После запуска попробуем добавить в поле комментария для любого из пользователей значение <b>добрый день! </b>
и сохранить изменения. Так как механизм проверки ввода включен по умолчанию, мы получим сообщение об ошибке (рис. 4.9).
Чтобы отключить проверку ввода для данного действия, для него необходимо добавить атрибут validateinputAttribute
так, как показано во фрагменте:
[AcceptVerbs(HttpVerbs.Post)]
[Authorize(Users = "Admin")]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Update(Guid? userId, string email,
string comment, bool isApproved, bool isLockedOut)
Атрибут ValidateInput
с параметром false указывает механизму ASP.NET MVC на то, что проверка параметров запроса для данного действия не требуется. После указания этого значения атрибута мы сможем задавать для значения Comment
данные с HTML-тегами. Сообщение будет выведено рядом с именем пользователя, как показано на рис. 4.10.
Механизм атрибута ValidateInputAttribute
позволяет в ряде случаев предоставить пользователю больший функционал, но использовать его следует с большой осторожностью. Отключая встроенный механизм проверки параметров запроса на опасное содержимое, вы таким образом берете на себя все проверки, связанные с вопросами безопасности. ValidateInputAttribute
с параметром false должен использоваться только в тех местах, где он действительно необходим, в общем случае его применение не рекомендуется и его следует избегать.