This blog is all about Cyber Security and IT

Sunday, June 28, 2026

XSS Attacks: Reflected, Stored, and DOM-Based Explained


Beginner’s Guide to Cross‑Site Scripting (XSS): Reflected, Stored, and DOM‑Based

XSS is one of the most common web security issues that every student should learn early. It allows a harmful script to run inside a user’s browser because a website did not handle user input safely. The result can be session theft, fake login forms, redirection to unsafe pages, or silent actions on behalf of the user. In this simple guide, you will learn how XSS happens, the major types, real‑world impact, and clear steps to prevent it. The goal is to build a clean mindset for writing secure code from day one.

What Is Cross‑Site Scripting?

Cross‑Site Scripting happens when a website includes untrusted input inside a page in a way that the browser treats it as code. The browser runs that code with the same permissions as the real page. Because the browser trusts the page, the harmful code can read cookies (unless protected), modify the DOM, or call site APIs as the user.

Why does this matter for students? If you create a feedback form, a forum, a college project portal, or even a simple portfolio with comments, you may accept text from users. Without the right checks, this text can turn into a script inside your page. So learning safe patterns now will save you from big problems later.

How XSS Works at a High Level

  • Input: The application accepts user input (search box, comment field, profile name, query parameter).
  • Processing: The app mixes this input into HTML, JavaScript, CSS, or a URL without proper encoding or sanitization.
  • Execution: The browser receives the page and treats part of that input as code. It runs it with the page’s privileges.

Important idea: The problem is not only “bad input.” The real root cause is unsafe output handling. You must encode or sanitize output based on the context (HTML text, attribute, URL, or JavaScript).

Three Main Types of XSS

1) Reflected XSS

In reflected XSS, harmful input comes from the request and is immediately reflected back in the response. For example, a search term from the URL is shown on the results page. If the site directly puts that term into HTML without encoding, an attacker can craft a special link and trick someone into clicking it. The script then runs only when the victim opens that crafted link.

Key traits:

  • Lives in the request and response cycle.
  • Usually needs a victim to click or visit a crafted URL.
  • Common on pages that echo query parameters.

2) Stored XSS

In stored XSS, the harmful input is saved on the server or database (like a comment, username, or forum post). When any user opens the affected page, the stored content is loaded and the script runs. This type is dangerous because one payload can impact many users without extra clicks.

Key traits:

  • Payload is permanently saved on the backend (or cache).
  • Affects every visitor of that page or feed.
  • Common in comment systems, chat messages, and profiles.

3) DOM‑Based XSS

In DOM‑Based XSS, the issue exists entirely on the client side. JavaScript on the page reads data from the URL, fragment, or other sources and writes it into the DOM using unsafe methods. No new page load from the server is needed. The browser processes the new DOM and runs the injected script.

Key traits:

  • Happens due to client‑side JavaScript logic.
  • Common sinks include innerHTML, document.write, and similar APIs.
  • Often triggered by URL fragments, query parameters, or postMessage data.

Real‑World Impact of XSS

  • Account takeover: If cookies or tokens are readable and not protected, a script can steal them.
  • Phishing inside the site: Fake login prompts that look totally genuine.
  • Silent actions: The script can call site APIs as the user (post messages, change settings).
  • Defacement: Changing page content to mislead users or harm brand reputation.
  • Malware delivery: Redirects to unsafe downloads or third‑party pages.

Common Mistakes That Lead to XSS

  • Directly inserting user input into HTML without encoding.
  • Using innerHTML or document.write with untrusted content.
  • Creating dynamic event handlers from user input (like onclick attributes).
  • Building URLs from untrusted input without proper encoding.
  • Relying only on client‑side checks; server must also enforce rules.

How to Prevent XSS (Student‑Friendly Checklist)

1) Encode Output Based on Context

Always encode before output, and match the context:

  • HTML text context: Convert special characters so they show as text, not code.
  • HTML attribute context: Also encode quotes and use safe attribute assignments.
  • URL context: Encode parameters before putting them into href or src.
  • JavaScript context: Avoid mixing user input inside inline scripts; prefer data attributes or JSON with safe parsing.

2) Use Framework Auto‑Escaping

Modern templating engines and frameworks (like React, Angular, Vue, or server templates that auto‑escape) help a lot. Keep auto‑escaping on by default. Avoid bypassing it unless you fully sanitize content.

3) Sanitize Only When You Need HTML

If your app truly needs to show user‑generated HTML (for example, rich text), use a trusted sanitization library that removes unsafe tags and attributes. Also keep the allowlist small.

4) Implement a Strong Content Security Policy (CSP)

CSP reduces the damage if something slips through. Start with a policy that blocks inline scripts and restricts sources. Example header:

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none';

Test in report‑only mode first to avoid breaking the site.

5) Protect Cookies and Sessions

  • Mark session cookies as HttpOnly and Secure so scripts cannot read them and they travel only over HTTPS.
  • Use SameSite to reduce cross‑site request risks.

6) Avoid Dangerous Patterns

  • Do not build HTML strings by concatenating user input.
  • Prefer textContent over innerHTML when inserting text.
  • Validate URLs before navigation or embedding.
  • Avoid inline event handlers and inline scripts.

7) Review and Test

  • Code review: Look for places that print user input.
  • Automated scanning: Run a security scanner during CI for basic checks.
  • Unit tests: Add tests for encoding functions and rendering templates.

Learning Path for Students

  • Read the OWASP Cheat Sheet Series on XSS prevention.
  • Practice building small pages that render user input safely using templates.
  • Understand browser security features: CSP, Trusted Types, sandboxed iframes.
  • Keep notes of common sinks (innerHTML, outerHTML, document.write, dangerous eval‑like functions) and safe alternatives.

Quick Myths and Facts

  • Myth: “We use HTTPS, so we are safe.” Fact: HTTPS protects data in transit, not against scripts running in the browser.
  • Myth: “We have a firewall; no worries.” Fact: A WAF helps but cannot replace correct encoding and secure coding.
  • Myth: “Only old sites have XSS.” Fact: Even modern SPAs can have DOM‑based issues if they use unsafe sinks.

Simple Example Scenarios (Conceptual)

  • Reflected: A search page shows the term typed by the user. Without encoding, a crafted link can make it run as code when opened.
  • Stored: A comment on a blog includes unsafe content that the site later shows to every reader, leading to automatic script execution.
  • DOM‑Based: Client script reads the URL fragment and injects it using innerHTML, causing the browser to execute that injected content.

Best Practices Summary

  • Encode output correctly for the target context.
  • Rely on framework auto‑escaping; avoid disabling it.
  • Use sanitization only when you must render HTML, with a tight allowlist.
  • Adopt CSP and, where possible, Trusted Types to block unsafe sinks.
  • Mark cookies with HttpOnly, Secure, and SameSite.
  • Review code paths that handle user input; write unit tests and run scanners.

FAQ

What is the main difference between the three types?

Reflected comes from the current request, stored is saved on the server and affects many users, and DOM‑based is triggered purely by client‑side JavaScript logic.

Does a modern frontend framework remove all risk?

No. Frameworks reduce risk with auto‑escaping, but unsafe operations or third‑party widgets can still create issues. You must follow secure patterns.

Is sanitizing input enough?

Input validation is useful, but output encoding is the core fix. Sanitization helps only when you truly need to render HTML. Otherwise, show user input as text.

Can I depend only on CSP?

CSP is a safety net, not a replacement. First fix the root cause in your code, then use CSP to add another layer.

Conclusion

XSS is easy to introduce but also very avoidable when you follow the right habits. Understand the three types, respect context‑aware encoding, use safer APIs, and apply defense‑in‑depth with CSP and secure cookies. As a student, if you build these practices into your daily coding, your web apps will be stronger, more trustworthy, and ready for real‑world users. Keep learning, keep testing, and write code that treats all user input as untrusted by default.

0 comments:

Post a Comment