Cross Site Scripting (XSS) Attack Prevention

Understanding the Problem

In this exercise, we're exploring Cross-Site Scripting (XSS) attacks using two applications: a legitimate app and a malicious app. The challenge is to understand how XSS attacks work and how to prevent them.

Key components we're dealing with:

Devising a Plan

Let's break this down into manageable steps:

  1. Set up both applications locally
  2. Examine how unescaped HTML behaves in the real application
  3. Test the vulnerability by creating a malicious tweet
  4. Implement HTML escaping to prevent the attack
  5. Verify the protection works

Carrying Out the Plan

Step 1: Initial Setup

# In first terminal:
cd malicious-app
npm install
npm run dev

# In second terminal:
cd real-app
npm install
npm run migrate
npm run seed
npm run dev

Step 2: Understanding the Vulnerability

Location: real-app/frontend/js/tweet-list.js

// Vulnerable code (allows XSS):
element.innerHTML = tweet.body;

// Safe code (prevents XSS):
const text = document.createTextNode(tweet.body);
element.appendChild(text);

Step 3: Example Attack Payload

<script>
    alert('if you see this alert pop up on your screen, then this page is prone to an XSS attack');
</script>

Real-world analogy: Think of XSS like putting a fake return address on a letter. When someone replies to that letter, they're actually sending their response to the attacker instead of the intended recipient. Similarly, when a website doesn't properly sanitize input, attackers can inject code that steals information from legitimate users.

Looking Back

Key lessons learned:

Advanced Solutions

Beyond basic HTML escaping, modern applications can implement:

Further Learning

Additional exercises to enhance understanding:

File Structure

project_root/
├── real-app/
│   ├── frontend/
│   │   └── js/
│   │       └── tweet-list.js
│   └── backend/
│       └── db/
│           └── seeders/
│               └── 20220128194409-malicious-tweets.js
└── malicious-app/
    └── [malicious app files]