InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. Subscribe to our weekly newsletter for the coolest infosec updates: https://weekly.infosecwriteups.com/

Follow publication

Modern XSS Challenges: Beyond the Basics

Dhanush N
InfoSec Write-ups
Published in
4 min readMar 18, 2025

Modern XSS Challenge By Dhanush Nehru

The landscape of web security has evolved dramatically, and the days of simple exploits like <script>alert(1)</script> or spinning up a quick python -m http.server to exfiltrate data are fading into obscurity.

Modern browser protections and heightened developer awareness have rendered many classic Cross-Site Scripting (XSS) techniques impractical outside of localhost environments.

We often see Proof of Concepts (PoCs) that ignore these contemporary hurdles, leaving us restless about their real-world applicability.

So, let’s dive into some frequent obstacles encountered when crafting full-fledged XSS exploits against today’s applications. This isn’t about reinventing the wheel or dissecting every browser’s XSS filter bypasses — rather, it’s about creatively adapting what we know to overcome application-specific barriers.

Photo by Luther.M.E. Bottrill on Unsplash

Here’s a rundown of common pitfalls and practical workarounds, illustrated with fresh examples.

The InnerHTML Trap: A Silent XSS Blocker

Dynamic web pages are the norm now, with the Document Object Model (DOM) constantly reshaped by API responses. A frequent (and risky) practice is injecting API-fetched content directly into an element’s innerHTML. Consider this scenario:

Example API Interaction

$ curl -X POST -H "Content-Type: application/json" --cookie "SESSION=abc123" \
-d '{"user_id":1234, "display_name":"<script>alert(1)</script>", "bio":"Hello"}' \
http://example.app/api/profile

{"status":"Profile updated"}

$ curl --cookie "SESSION=abc123" http://example.app/api/profile/name

{"display_name":"<script>alert(1)</script>"}

Client-Side Code

function fetchDisplayName() {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
const response = JSON.parse(xhr.responseText);
document.getElementById('profile-name').innerHTML = response.display_name;
}
};
xhr.open("GET", "/api/profile/name", true);
xhr.send();
}

Create an account to read the full story.

The author made this story available to Medium members only.
If you’re new to Medium, create a new account to read this story on us.

Or, continue in mobile web

Already have an account? Sign in

Published in InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. Subscribe to our weekly newsletter for the coolest infosec updates: https://weekly.infosecwriteups.com/

Written by Dhanush N

Engineer, Chess enthusiast & Tech tinkerer. I build, break and hack systems while exploring the art of problem-solving. 🔗 https://www.youtube.com/@dhanushnehru

No responses yet

Write a response