Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Cross-site scripting: Explanation and prevention with Go

June 28, 2022
Sandipan Roy
Related topics:
GoSecurity
Related products:
Developer Tools

Share:

    Have you ever encountered a pop-up when visiting a web page or browsing a particular item on a site? Imagine if these pop-ups were carriers that delivered malicious payloads to your devices or captured confidential information. This is a type of cyber attack called cross-site scripting, or XSS. Cross-site scripting is one of the most common attacks in 2022, and it made the OWASP top 10 web application security risks. Let's take a tour of cross-site scripting and learn how an attacker executes malicious JavaScript code on input parameters, creates pop-ups to deface web applications, and can hijack an active user session.

    How JavaScript is used in XSS attacks

    A dynamic web application is set up with three key features:

    1. HTML specifies the complete structure.
    2. CSS configures the overall look and feel.
    3. JavaScript adds powerful interactions to the application, such as warning popups, rollover effects, drop-down menus, and more.

    JavaScript is the most popular scripting language. 95% of all websites are built and run via JavaScript. It implements interesting and powerful interactive features, and acts according to the user's actions.

    Actions associated with executing JavaScript code include:

    • onclick: Executes JavaScript when the user clicks on a box or link.
    • onload: Executes JavaScript after a web page or image is completely loaded. An example:
      <body onload=alert('Welcome to Red Hat')>
    • onmouseover: Triggers JavaScript when the mouse passes over a URL link. An example:
      <a onmouseover=alert("redhat.com")>Contribute</a>
    • onmouseout: Triggers JavaScript if the mouse moves out of the window without clicking a URL.
    • onunload: Triggers JavaScript when the user leaves the web page by closing the browser or clicking a link.

    XSS is a client-side code injection attack. In this kind of attack, websites are injected with malicious JavaScript code. XSS occurs when input parameters have not been correctly handled or validated in web applications, which allows an attacker to send malicious JavaScript code to a different end user. The end user's browser does not recognize it as a malicious script and falls into the XSS trap. This type of attack does not threaten users directly with a payload, but the attacker targets the XSS vulnerability by injecting a malicious script on a web page that seems to be a real part of the website. Thus, when any user visits this website, the XSS-afflicted website sends malicious JavaScript code to the user's browser without their knowledge.

    Types of XSS attacks

    There are a variety of types of XSS attacks, divided into three major categories:

    • Stored XSS, also known as permanent or type I XSS. In stored attacks, target servers store the injected script forever. The scripts maybe be stored in a database, on servers, or in forum comments. The victim unwittingly downloads that stored script from the server when attempting to access these resources.
    • Reflected XSS, also known as type-II or non-persistent XSS. These attacks happen when a web application instantly acknowledges the user's input without inspecting what has been entered. The attacker sends a malicious link via phishing to trick the user, and not store it on the webserver. There are two major types of reflected XSS: reflected XSS GET and reflected XSS POST.
    • DOM-based XSS: DOM-based XSS is a well-known vulnerability that happens in a document object model (DOM). The DOM defines web page segments such as the title, heading, table, forms, or a well-structured HTML page. If HTML documents are loaded into a web browser, they are transformed into a document object.

    3 defense strategies for XSS attacks

    Preventing cross-site scripting (XSS) attacks can be complicated, but these basic defense strategies are effective.

    Have a content security policy

    A content security policy (CSP) is a browser feature that allows you to create source lists for client-side web application resources, including JavaScript, CSS, and images. The CSP directs the browser to execute or display resources from specific sources using a special HTTP header.

    In this example, the server only allows access to documents that are loaded over HTTPS via the single origin developers.redhat.com:

    
    Content-Security-Policy: default-src https://developers.redhat.com
    
    

    Deploy the X-XSS-Protection header

    The XSS filter in recent web browsers is enabled by the X-XSS-Protection HTTP response header. Because the header is normally enabled by default, its function is to re-enable the filter for a specific website if the user has disabled it.

    Make use of modern development frameworks

    Modern JavaScript frameworks like AngularJS and ReactJS, along with server-side templating systems like Go Templates, offer good protection against reflected cross-site scripting.

    Vulnerable code examples

    In the previous sections, we examined JavaScript and its vulnerabilities. But a secure backend system like Go's HTTP Package can block misleading JavaScript functionality. Let's use this package to illustrate some analytic techniques.

    In our first example, the server() method reads the parameter XYZ from the query string and returns it in the HTTP response. This method also handles HTTP GET requests. The http.DetectContentType function determines the default content-type response header.

    
    package main
    import "io"
    import "net/http"
    
    func server(w http.ResponseWriter, r *http.Request) {
     io.WriteString(w, r.URL.Query().Get("XYZ"))
    }
    
    func main() {
     http.HandleFunc("/", server)
     http.ListenAndServe(":5000", nil)
    }
    

    The content-type is set to text/plain when delivering a payload with XYZ=OpenSource, as you can see using a browser's developer tool (see Figure 1). This is not dangerous and is presented by the browser as plain text.

    Firefox developer tool
    Figure 1: Firefox developer tool shows the network header request.
    Figure 1: Firefox's developer tool shows the network header request.

    When I submit a request using XYZ=<script>alert("RedHat")</script>, the response's Content-Type is set to text/html, exposing the user to a cross-site scripting attack (see Figure 2).

    Firefox developer tool
    Figure 2: Executing our malicious JavaScript code processed by the backend.

    This JavaScript delivery can do harmful things, and we must fix it. Fortunately, changing a simple package in Go can prevent it.

    The example vulnerability can be minimized by encoding the user-controlled parameter's output. Several output encoding routines are included in the html/template package in Go. The problem in this example can be solved by using the HTMLEscapeString method to perform output encoding on the user-supplied input:

    
    import "io"
    import "net/http"
    
    func server(w http.ResponseWriter, r * http.Request) {
        encodedParam = template.HTMLEscapeString(r.URL.Query().Get("XYZ"))
        io.WriteString(w, encodedParam)
    }
    
    func main() {
        http.HandleFunc("/", server)  http.ListenAndServe(":8080", nil)
    }
    
    

    Now let's consider a second example. The server() function reads the parameter error from the query string and adds it to the template (text/template module) that handles HTTP GET requests. The http.DetectContentType function determines the default content-type response header.

    
    import "net/http"
    import "text/template"
    
    func server(w http.ResponseWriter, r *http.Request) {
    error := r.URL.Query().Get("XYZ")
    tmpl := template.New("ERROR")
    tmpl, _ = tmpl.Parse(`{{define "T"}}{{.}}{{end}}`)
    tmpl.ExecuteTemplate(w, "T", error)
    }
    
    func main() {
    http.HandleFunc("/", server)
    http.ListenAndServe(":5000", nil)
    }
    
    

    When I submit a request using XYZ=<script>alert("RedHat")</script>, the response's content-type sets to text/html, exposing the user to cross-site scripting, as shown in Figure 3.

    Firefox developer tool
    Figure 3: Executing the malicious JavaScript code and successfully injecting our code.

    To fix this vulnerable code, replace the text/template import with html/template with built-in output encoding capabilities:

    
    import "net/http"
    import "html/template"
    
    func server(w http.ResponseWriter, r *http.Request) {
        error: = r.URL.Query().Get("XYZ")
        tmpl: = template.New("ERROR")
        tmpl, _ = tmpl.Parse(`{{define "T"}}{{.}}{{end}}`)
        tmpl.ExecuteTemplate(w, "T", error)
    }
    
    func main() {
        http.HandleFunc("/", server)
        http.ListenAndServe(":5000", nil)
    }

    When a request with XYZ=<script>alert("RedHat")</script> is sent, the updated code successfully encodes the payload (see Figure 4). The fixed backend code has successfully filtered the attack, preventing it from executing malicious JavaScript code.

    Firefox developer tool
    Figure 4: Executing malicious JavaScript code but backend blocked the request.
    Figure 4: The backend blocks a request for malicious JavaScript code.

    Conclusion

    Cutting-edge programming languages like Go make it easy to fix security issues such as cross-site scripting, server-side request forgery, and comment injections. With secure coding practices and continuous security testing, you can prevent various cyber-attacks. Learn more about secure coding practice by reviewing the OWASP secure coding practice guide, or read Black Hat Go for information about security penetration testing.

    Last updated: February 5, 2024

    Recent Posts

    • Expand Model-as-a-Service for secure enterprise AI

    • OpenShift LACP bonding performance expectations

    • Build container images in CI/CD with Tekton and Buildpacks

    • How to deploy OpenShift AI & Service Mesh 3 on one cluster

    • JVM tuning for Red Hat Data Grid on Red Hat OpenShift 4

    What’s up next?

    Podman is one of the next-generation container tools (along with buildah and skopeo) included in Red Hat Enterprise Linux 7 and RHEL 8. The Podman Basics Cheat Sheet covers all of the commands that focus on images, containers, and container resources.

    Get the cheat sheet
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue