Tricky JavaScript: XSS attack and its types

Lesson#2 of 12 in topic Theory


Yeah, it's not rated as number 1 in the OWASP list. It's calmly sits at its fifth number - injections. And we start exactly here - because injections are really simple to understand. 

Injections are the most tested web vulnerability, which has many variations and approaches. Previously, it was ranked as third most popular web vulnerability

Okay, so what is XSS attack?


XSS (Cross-Site Scripting) is a web security vulnerability that allows an attacker to inject malicious JavaScript into a website, which then runs in the browser of other users.

Important idea to remember:

❗ XSS is not about hacking the server
❗ XSS is about tricking the browser into running attacker’s code

If a website blindly trusts user input, an attacker can turn that input into executable JavaScript.


Why is XSS dangerous?


With XSS, an attacker can:

  • Steal cookies or session tokens

  • Act as the victim user (account takeover)

  • Change page content

  • Redirect users to fake pages

  • Log keystrokes (password stealing)

And all of this happens inside the victim’s browser, under the website’s domain 😬


Main Types of XSS

1. Stored XSS (Persistent)


What happens?
Malicious input is saved on the server (database) and shown to other users later.

Example scenario:

  • A comment form

  • A profile bio

  • A forum post

Example:

  1. Attacker posts a comment containing JavaScript

  2. Website saves it

  3. Every user who opens the page runs that script

This is the most dangerous type because it affects many users automatically.


2. Reflected XSS (Non-persistent)


What happens?
The malicious input is sent in the request (URL or form) and immediately reflected in the response.

Example scenario:

  • Search pages

  • Error messages

  • Filters

Example flow:

  1. Attacker sends a special link to a victim

  2. Victim clicks the link

  3. Website reflects the input without validation

  4. Script executes in victim’s browser

No database involved — but still dangerous.


3. DOM-based XSS


What happens?
The vulnerability exists entirely in frontend JavaScript.

The server may be safe, but the page’s JS code:

  • Reads data from location, hash, or URL

  • Inserts it into the page using unsafe methods

Common dangerous JS methods:

  • innerHTML

  • document.write

  • eval()

If user-controlled data goes into these — boom 💥


Simple XSS Example

Vulnerable code (❌):

<div id="output"></div>

<script>
  const name = new URLSearchParams(window.location.search).get("name");
  document.getElementById("output").innerHTML = name;
</script>

If the value of name contains JavaScript, it will be executed.


Safe version (✅):

document.getElementById("output").textContent = name;

Why this works:

  • textContent treats input as text

  • It does NOT execute HTML or JavaScript


How to Defend Against XSS

1. Never trust user input 🚫

User input includes:

  • Forms

  • URLs

  • Cookies

  • Headers

  • LocalStorage

Always assume input is malicious.


2. Escape output (MOST IMPORTANT)

Before displaying user data:

  • Escape <, >, ", ', &

Most frameworks do this automatically:

  • Vue

  • React

  • Angular

  • Laravel Blade

  • Twig

Problem appears when developers bypass protections.


3. Use safe DOM methods

✅ Safe:

  • textContent

  • innerText

  • setAttribute (carefully)

❌ Dangerous:

  • innerHTML

  • document.write

  • eval


4. Validate input (but don’t rely only on it)

Validation is useful, but:

  • Attackers can bypass filters

  • Output escaping is still required

Best practice:

Validate input + escape output


5. Use Content Security Policy (CSP)

CSP tells the browser:

  • Which scripts are allowed

  • Where scripts can load from

Even if XSS exists, CSP can block execution.

Objectives

  1. #1
  2. #2
  3. #3
  4. #4