Skip to main content

Insecure Processing of Data

Fixing Cross-Site Scripting

About XSS

What is Cross-Site Scripting?

Cross-site scripting (XSS) is a type of security vulnerability that allows attackers to inject malicious code into web pages viewed by other users. This occurs when an application fails to properly sanitize user input and injects untrusted data into a web page without validating or encoding it.

XSS attacks can occur in different forms, such as reflected, stored, or DOM-based, and can affect various types of web applications, including social media, e-commerce, and online banking sites.

Attackers can use various techniques, such as phishing emails, web forms, or malicious links, to trick users into visiting or interacting with web pages that contain malicious code.

Check out this video for a high-level explanation:

What is the impact of Cross-Site Scripting?

Cross-site scripting (XSS) can lead to various security threats and risks, such as:

  • Information theft: XSS attacks can steal sensitive information, such as login credentials, credit card details, or other personally identifiable information, by injecting malicious code that collects and transmits user data to attackers.
  • Account hijacking: XSS attacks can hijack user sessions by injecting malicious code that takes over user sessions, allowing attackers to perform unauthorized actions on the website or gain access to user accounts.
  • Data tampering: XSS attacks can modify or delete data on a website by injecting malicious code that alters the content of web pages, leading to data tampering, data corruption, or other types of malicious activities.
  • Malware distribution: XSS attacks can distribute malware by injecting malicious code that downloads and installs malicious software on the user's computer, leading to malware infections or other types of cyber attacks.

Overall, XSS attacks can compromise the confidentiality, integrity, and availability of data, leading to a range of security threats and risks.

How to prevent Cross-Site Scripting?

To prevent XSS vulnerabilities, you can take the following steps:

  • Input validation and sanitization: Ensure that all user input is validated and sanitized before being used to generate web pages or manipulate other data. Input validation should include validating the data type, length, and format, and filtering out any special characters that could be used to inject malicious code.
  • Output encoding: Encode all output to protect against XSS attacks. Use output encoding techniques such as HTML entity encoding, URL encoding, and JavaScript encoding to encode user input and output to the browser.
  • Use security headers: Implement security headers to protect against XSS attacks, such as Content-Security-Policy (CSP) and X-XSS-Protection. CSP can help prevent XSS attacks by allowing only trusted sources of content to be loaded on a page, while X-XSS-Protection can help prevent the browser from rendering pages that contain malicious scripts.
  • Session management: Implement secure session management mechanisms, such as session cookies, to protect against session hijacking and other attacks.
  • Secure coding practices: Use secure coding practices to prevent XSS vulnerabilities. This includes using libraries and frameworks that are designed to prevent XSS attacks, testing code for vulnerabilities, and using secure coding practices such as input validation and output encoding.
  • Regular security audits: Regularly audit your system for security vulnerabilities, including XSS vulnerabilities. Use automated tools and manual testing to identify potential issues and fix them before they can be exploited.



Explanation & Prevention


Option A: Perform output encoding

Solution-specific references:

  1. Go through the issues that GuardRails identified in the PR/MR.

  2. Look for patterns like this:

    def index(conn, %{"dangerous" => dangerous}) do
    put_resp_content_type(conn, "text/html")
    |> send_resp(200, dangerous)


    def index(conn, %{"dangerous" => dangerous}) do
    html conn, "<h1>\#{dangerous}</h1>"


    <%= raw(@dangerous_user_input) %>
    # This bypasses the in-built escaping and has to be used with care. Ensure that the
    # content is not coming from request parameters, and is a safe hard-coded string.
  3. And use safe alternatives like:

    def index(conn, %{"dangerous" => dangerous}) do
    put_resp_content_type(conn, "text/plain")
    |> send_resp(200, dangerous)

    or use a function URI.decode to encode dangerous characters :

    def index(conn, %{"dangerous" => dangerous}) do
    html conn, "<h1>\#{URI.encode(dangerous)}</h1>"
  4. Test it

  5. Ship it 🚢 and relax 🌴