Understanding XSS vulnerabilities
📘 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 : <script>alert("hello")</script>
<!-- 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
Note : on most of the template languages escape by default html :
Understanding CSRF vulnerabilities
In this article, we will explore how CSRF vulnerabilities work and how to prevent them
Understanding SQL injection vulnerabilities
In this article, we will explore how SQL injection vulnerabilities work and how to prevent them
Practice code with the "Quick Sort" algorithm
Enhance your coding skills by learning how the Quick Sort algorithm works!
The SOLID/STUPID principles
Learn what are the SOLID and STUPID principles with examples
Create a Docker Swarm playground
Let's create Docker Swarm playground on your local machine
Create an Ansible playground with Docker
Let's create an Ansible playground with Docker
HashiCorp Vault - Technological watch
Learn what is HashiCorp Vault in less than 5 minutes !
Setup a Kubernetes cluster with K3S, Traefik, CertManager and Kubernetes Dashboard
Let's setup step by step our own K3S cluster !