Understanding XSS vulnerabilities

In this article, we will explore how XSS vulnerabilities work and how to prevent them
Saturday, September 13, 2025

📘 What is XSS vulnerability?

Cross-Site Scripting (XSS) is a type of security vulnerability typically found in web applications. It allows attackers to inject malicious scripts (usually JavaScript) into content that other users will view. When the victim’s browser loads the page, it executes the script as if it came from a trusted source.

🧪 Demonstration

Here’s a simplified vulnerable Go web app:

package main
import (
"fmt"
"net/http"
)
func searchHandler(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query().Get("q")
w.Header().Set("Content-Type", "text/html; charset=utf-8")
// ❌ Vulnerable: user-supplied query is rendered without sanitization, enabling XSS
fmt.Fprintf(w, "You searched : %s", query)
}
func main() {
http.HandleFunc("/search", searchHandler)
fmt.Println("Server running at http://localhost:8080")
http.ListenAndServe(":8080", nil)
}

This application displays the user’s search query in the response.

If we open the URL http://localhost:8080/search?q=hello, we expect to see :

You searched : hello

💣 Exploiting the vulnerability

This vulnerability can be exploited by crafting a URL like:

http://localhost:8080/search?q=<h1>hello</h1>

In this example, we inject HTML tags into the query string. The browser interprets these tags and renders them as actual HTML—in this case, displaying “hello” as a heading. This alters the intended layout of the page.

We can take this further by injecting JavaScript using a <script> tag:

http://localhost:8080/search?q=<script>alert("hello")</script>

When this URL is opened, the browser executes the embedded JavaScript, triggering an alert popup. While this example is harmless, it demonstrates how arbitrary scripts can be executed—opening the door to more serious attacks.

For instance, an attacker could embed a malicious payload in a forum comment:

http://localhost:8080/search?q=<img src="/" onerror="window.location.href='https://www.alexandre-hublau.com'" />

This payload uses an image tag with a broken source and an onerror handler to redirect users to a malicious site. Beyond redirection, attackers could use similar techniques to steal cookies, log keystrokes, or perform other malicious actions—all without the user’s consent.

🛡️ How to prevent XSS attacks

To mitigate XSS vulnerabilities, it’s essential to escape any user-generated content before rendering it in the browser. In Go, this can be done using the html.EscapeString() function, which safely encodes special HTML characters.

Here’s the updated code:

package main
import (
"fmt"
"html"
"net/http"
)
func searchHandler(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query().Get("q")
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintf(w, "You searched : %s", html.EscapeString(query))
}
func main() {
http.HandleFunc("/search", searchHandler)
fmt.Println("Server running at http://localhost:8080")
http.ListenAndServe(":8080", nil)
}

Now, if we visit http://localhost:8080/search?q=<script>alert("hello")</script>, the server responds with the following content:

You searched : &lt;script&gt;alert(&#34;hello&#34;)&lt;/script&gt;
<!-- The browser will render like this : -->
You searched : <script>alert("hello")</script>

In this case, the special characters in the query are properly escaped, so the browser treats them as plain text rather than executable code. As a result, the script is not executed, and the page remains safe and intact. The user still sees their input reflected on the page, but without any unintended behavior or layout disruption.


If you use another language, you may find the equivalent function. In PHP, you can use htmlspecialchars() : https://www.php.net/htmlspecialchars


Recommended articles