# 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).

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

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

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

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

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

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

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

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

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

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

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

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

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

    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 атаки необходимо обрабатывать данные либо перед записью в базу данных, либо перед отображением на странице.

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

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

Анализатор также считает источниками небезопасных данных параметры методов, доступных из других сборок. Более подробно эта тема раскрыта в заметке "Почему важно проверять значения параметров общедоступных методов".

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

    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':

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

Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки непроверенного использования чувствительных данных (ввода пользователя, файлов, сети и пр.).

Данная диагностика классифицируется как:

CWE-79 OWASP-5.3.3