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

The analyzer detected tainted data that might be used to execute a malicious script. XSS vulnerability may occur.

OWASP Top 10 Application Security Risks 2017 provides a separate category for Cross-Site Scripting (XSS): A7:2017-Cross-Site Scripting (XSS).

HTTP request parameters, HTTP request body, and HTML input fields are frequent targets for XSS attacks.

Consider the simplest example of XSS delivered through URL parameters:

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

In this case, the user inputs a string in the 'TargetSiteUrl.Text' text field and runs the code. The webpage defined in 'TargetSiteUrl.Text' opens.

Suppose the webpage displays the string set in the 'inputData' URL parameter.

If a user defines the <script>alert("XSS Injection")</script> element in the 'inputData' URL parameter, this code is executed when the browser renders the webpage. The string used in the script is displayed in a separate window:

The executed JavaScript code in the URL parameter is an XSS attack. By means of social engineering, an attacker can make a user insert a similar request with a malicious script in the 'TargetSiteUrl.Text' field. As a result, an attacker can gain access to a user account. For example, a hacker might use browser cookies. Thus, an attacker may steal confidential data or perform malicious actions on behalf of the user.

This XSS attack would have failed if the string in the 'TargetSiteUrl.Text' field had encoded special HTML characters before being used in the 'WebBrowser.Navigate' method:

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

In this case, the malicious script would not be executed. The page would simply display the following code:

Also, an attacker may use website input fields to make an XSS attack. Some websites allow users to leave comments and view other visitors' comments after signing in. A website database stores such comments. Only authorized users may view comments on the webpage. If comments do not encode special HTML characters before being displayed, an interesting XSS attack is possible.

An attacker might sign up and leave a comment containing a malicious script, which will be saved in the database. Then, this comment is visible to all authorized users. If a webpage displays a comment where special HTML characters aren't encoded, an attacker may execute a malicious script in the browser of each authorized user who decides to view comments. Thus, an attacker may get cookies of several users at once. If a cookie stores an authentication token, the attacker will have some time to log in to the other users' accounts.

An example of code which displays users comments on the webpage:

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

To prevent such XSS attack, a programmer should process data either before recording it to a database or before its rendering on a website.

The fixed code for displaying comments stored in the database (the data is encoded before being displayed) can be as follows:

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

The analyzer also considers public methods' parameters potential sources of tainted data. This topic is covered in detail in the note "Why You Should Check Values of Public Methods' Parameters".

Consider an example of code:

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

While analyzing the source code of the 'ProcessUrlQuery' method, the analyzer issues a low certainty level warning on the 'OpenWebPage' method. The analyzer detects tainted data passed from the 'urlQuery' parameter to the 'Navigate' method.

The 'urlQuery' parameter is used in string concatenation. That's why the 'urlRequest' variable also contains tainted data. Then, the 'OpenWebPage' method receives 'urlRequest'. 'urlRequest' serves as the 'Navigate' method's argument. Thus, user input may get into the 'Navigate' method unverified. That makes this code vulnerable to XSS.

You can prevent XSS attacks the way described in the example above - just encode the request string before passing the argument to the 'Navigate' method:

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

This diagnostic is classified as:

CWE-79 OWASP-5.3.3