﻿# V5610\. OWASP\. Possible XSS vulnerability\. Potentially tainted data might be used to execute a malicious script\.

Анализатор обнаружил ситуацию, при которой данные, полученные из внешнего источника, могут быть использованы для запуска вредоносного скрипта\. Подобный код может быть уязвим к XSS\.

XSS выделен в отдельную категорию рисков в OWASP Top 10 Application Security Risks 2017: [A7:2017\-Cross\-Site Scripting \(XSS\)](https://owasp.org/www-project-top-ten/2017/A7_2017-Cross-Site_Scripting_(XSS))\.

К XSS чаще всего уязвимы аргументы строки HTTP запроса, тело HTTP запроса и поля ввода HTML страниц\.

Рассмотрим простейший пример XSS через параметры URL запроса:

```cpp
void OpenHtmlPage()
{
  WebBrowser.Navigate(TargetSiteUrl.Text);
}
```

В данном случае пользователь в интерфейсе программы вводит в текстовое поле 'TargetSiteUrl\.Text' строку и нажимает на кнопку\. После нажатия кнопки в интерфейсе приложения открывается страница сайта, указанного в 'TargetSiteUrl\.Text'\. 

Допустим, на веб странице отображается строка, указанная в URL параметре 'inputData'\.

![V5610_ru/image1.png](https://import.viva64.com/docx/blog/V5610_ru/image1.png)

В таком случае, если в URL параметре 'inputData' в строке запроса к странице указать элемент <script\>alert\("XSS Injection"\)</script\>, то при рендеринге страницы этот код будет выполнен, и в отдельном окне отобразится строка, использованная в скрипте:

![V5610_ru/image2.png](https://import.viva64.com/docx/blog/V5610_ru/image2.png)

Выполнение JavaSсript кода, переданного в URL параметре, является XSS атакой\. Благодаря социальной инженерии злоумышленник может убедить пользователя вставить подобный запрос с вредоносным скриптом в поле 'TargetSiteUrl\.Text'\. В результате выполнения скрипта у злоумышленника может оказаться информация для доступа к аккаунту пользователя\. Например, cookie, которые хранились в браузере\. Воспользовавшись ей, он сможет похитить конфиденциальные данные или выполнить вредоносные действия от имени пользователя\.

Данная XSS атака была бы изначально неудачной, если бы строка, которую ввел пользователь в поле 'TargetSiteUrl\.Text', перед использованием в методе 'WebBrowser\.Navigate' кодировала спец\. символы HTML:

```cpp
void OpenHtmlPage()
{
  var encodedUrl = System.Net.WebUtility.HtmlEncode(TargetSiteUrl.Text);
  WebBrowser.Navigate(encodedUrl);
}
```

В таком случае код вредоносного скрипта не выполнился бы, а просто отобразился на странице:

![V5610_ru/image4.png](https://import.viva64.com/docx/blog/V5610_ru/image4.png)

Также XSS возможен и через поля ввода на сайте\. Например, функционал сайта предоставляет возможность оставлять комментарии и просматривать комментарии других посетителей сайта, если вы авторизовались на сайте\. Добавленные комментарии сохраняются в базу данных сайта и отображаются на странице комментариев, которая видна только авторизированным пользователям\. Если перед отображением комментариев в них не кодируются спец\. символы HTML, то возможна интересная XSS атака\.

Злоумышленник зарегистрируется на сайте и оставит комментарий, в котором содержится вредоносный скрипт\. Комментарий со скриптом сохранится в базу данных\. После этого все авторизированные пользователи смогут просмотреть этот комментарий\. Если при отображении комментария на странице в нем не кодируются спец\. символы HTML, то вредоносный скрипт будет выполнен в браузере каждого авторизированного пользователя, который решил посмотреть комментарии\. Таким образом злоумышленник сможет получить cookie не одного, а нескольких пользователей сайта\. Если в cookie сохраняется токен авторизации на сайте, то он некоторое время будет иметь возможность войти в аккаунты других пользователей сайта\.

Пример кода, отображающего комментарии пользователей на странице сайта:

```cpp
using (var sqlConnection = ....)
{
  var command = ....;
  ....
  var reader = command.ExecuteReader();
  while (reader.Read())
  {
    ....
    var userComment = reader.GetString(1);
    ....
    Response.Write("<p>");
    Response.Write(userComment);
    Response.Write("</p>");
    ....
  }
}
```

Для защиты от подобной XSS атаки необходимо обрабатывать данные либо перед записью в базу данных, либо перед отображением на странице\.

Исправленный код отображения комментариев из базы данных \(данные кодируются перед отображением\) может быть таким:

```cpp
using (var sqlConnection = ....)
{
  var command = ....;
  ....
  var reader = command.ExecuteReader();
  while (reader.Read())
  {
    ....
    var userComment = reader.GetString(1);
    var encodedComment = WebUtility.HtmlEncode(userComment);
    ....
    Response.Write("<p>");
    Response.Write(encodedComment);
    Response.Write("</p>");
    ....
  }
}
```

Анализатор также считает источниками небезопасных данных параметры методов, доступных из других сборок\. Более подробно эта тема раскрыта в заметке "[Почему важно проверять значения параметров общедоступных методов](https://pvs-studio.ru/ru/blog/posts/csharp/0835/)"\.

Рассмотрим пример кода:

```cpp
public class UriHelper
{
  WebBrowser WebBrowser = new WebBrowser();

  private string _targetSite = "http://mysite.com";

  public void ProcessUrlQuery(string urlQuery)
  {
    var urlRequest = _targetSite + "?" + urlQuery;
    OpenWebPage(urlRequest);
  }

  private void OpenWebPage(string urlWithQuery)
  {
    WebBrowser.Navigate(urlWithQuery);
  }
}
```

В данном случае анализатор выдаст предупреждение низкого уровня достоверности при анализе исходного кода метода 'ProcessUrlQuery' на вызов метода 'OpenWebPage'\. Анализатор отследил передачу небезопасных данных из параметра 'urlQuery' в метод 'Navigate'\. 

Параметр 'urlQuery' используется при конкатенации строк, из\-за чего переменная 'urlRequest' также будет содержать небезопасные данные\. Далее 'urlRequest' передаётся в метод 'OpenWebPage', где выступает в качестве аргумента метода 'Navigate'\. Таким образом, пользовательский ввод может попасть в метод 'Navigate' без проверки, из\-за чего данный код уязвим к XSS\.

Защититься от XSS в этом коде возможно тем же способом, что и в примере ранее \- просто кодировать строку запроса перед передачей в метод 'Navigate':

```cpp
public class UriHelper
{
  WebBrowser WebBrowser = new WebBrowser();

  private string _targetSite = "http://mysite.com";

  public void ProcessUrlQuery(string urlQuery)
  {
    var urlRequest = _targetSite + "?" + urlQuery;
    OpenWebPage(urlRequest);
  }

  private void OpenWebPage(string urlWithQuery)
  {
    var encodedUrlWithQuery = 
      System.Net.WebUtility.HtmlEncode(urlWithQuery);
    WebBrowser.Navigate(encodedUrlWithQuery);
  }
}
```