Skip to content

Cross Site Scripting (XSS)

What does this mean ?

Cross-site Scripting (XSS) is a type of code injection attack that occurs on the client side. The attacker intends to run harmful scripts in the victim's web browser by embedding malicious code in a genuine web page or online application. The real attack takes place when the victim hits the malicious code-infected web page or online application. The web page or web application serves as a vehicle for the malicious script to be sent to the user's browser. Forums, message boards, and online pages that enable comments are vulnerable vehicles that are frequently utilized for Cross-site Scripting attacks.

What can happen ?

An attacker can use XSS to transmit a malicious script to a user who is not expecting it. The browser of the end-user has no means of knowing that the script should not be trusted and will run it anyhow. Because it believes the script came from a reliable source, the malicious script has access to any cookies, session tokens, or other sensitive information stored by the browser and utilized with that site. These types of vulnerabilities can even rewrite the HTML page's content.

Recommendation

In general, properly avoiding XSS vulnerabilities would almost certainly need a mix of the following measures:

  • Filter the user's input: When receiving user input, filter it as precisely as possible depending on what is anticipated or legitimate input.
  • Encode data on output: Encode user-controllable data in HTTP responses at the point when it's returned by the webserver/application to prevent it from being perceived as active content. Depending on the output context, this might need the use of a mix of HTML, URL, JavaScript, and CSS encoding.
  • Use suitable response headers: To avoid XSS in HTTP responses that aren't supposed to contain any HTML or JavaScript, use the Content-Type and X-Content-Type-Options headers to guarantee that browsers read the responses correctly.
  • Content Security Policy (CSP): As a last line of defense, you may utilize Content Security Policy (CSP) to mitigate the severity of any remaining XSS vulnerabilities.

Sample Code

Vulnerable :

public class TestController : Controller
{
    [HttpGet(""{myParam}"")]
    public string Get(string myParam)
    {
        return "value " + myParam;
    }
}

Non Vulnerable :

public class TestController : Controller
{
    [HttpGet(""{myParam}"")]
    public string Get(string myParam)
    {
        return "value " + HttpUtility.HtmlEncode(myParam);
    }
}

Vulnerable :

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String name = req.getParameter("name");
  PrintWriter out = resp.getWriter();
  out.write("Hello " + name); // Noncompliant
}

Non Vulnerable :

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String name = req.getParameter("name");
  String encodedName = org.owasp.encoder.Encode.forHtml(name);
  PrintWriter out = resp.getWriter();
  out.write("Hello " + encodedName);
}

Vulnerable :

$name = $_GET["name"];
echo "Welcome $name"; // Noncompliant

Non Vulnerable :

$name = $_GET["name"];
$safename = htmlspecialchars($name);
echo "Welcome $safename";

Vulnerable :

app.get("/search", (req,res) => {
    item = req.query['item']
    res.send("<p>You searched for:"+ item+"</p>")
})

Non Vulnerable :

app.get("/search", (req,res) => {
    item = req.query['item']
    res.send("<p>You searched for:"+ escape(item)+"</p>")   
})

Vulnerable :

package main

import "io"
import "net/http"

func server(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, r.URL.Query().Get("query"))
}

func main() {
    http.HandleFunc("/", server)
    http.ListenAndServe(":8000", nil)
}

Non Vulnerable :

import "io"
import "net/http"

func server(w http.ResponseWriter, r * http.Request) {
    encodedParam = template.HTMLEscapeString(r.URL.Query().Get("query"))
    io.WriteString(w, encodedParam)
}

func main() {
    http.HandleFunc("/", server)  
    http.ListenAndServe(":8000", nil)
}

Vulnerable :

<% user = User.find(10) %>
<p>Hi <%= user.first_name %>!</p>

Non Vulnerable :

<% user = User.find(10) %>
<p>Hi <%= user.first_name.html_safe %>!</p>

References