Cross-Site Scripting in the AI Era
XSS allows attackers to inject malicious scripts into web pages viewed by other users. AI coding tools—especially those focused on frontend development—frequently generate XSS vulnerabilities.
What Is XSS?
When user-controlled data is rendered as HTML without proper encoding:
Attackers can:
- Steal session cookies
- Redirect users to phishing sites
- Modify page content
- Perform actions as the user
How AI Tools Generate XSS
dangerouslySetInnerHTML in React
// AI-generated (VULNERABLE)
function Comment({ content }) {
return
}AI generates this when you ask for:
- "Rich text display"
- "HTML content rendering"
- "Markdown preview"
Direct DOM Manipulation
// AI-generated (VULNERABLE)
document.getElementById('output').innerHTML = userInputv0 and Similar Tools
v0 and frontend-focused AI tools often generate:
// AI-generated (VULNERABLE)
The markdown library might be safe, but the pattern teaches unsafe habits.
XSS Types AI Generates
Stored XSS
User input saved to database, rendered for other users:
// Comment is from database, originally from user
Reflected XSS
User input from URL rendered immediately:
// AI-generated search results
const { query } = useSearchParams()
return Results for:
DOM-Based XSS
Client-side JavaScript manipulates DOM unsafely:
// AI-generated URL hash handler
const hash = window.location.hash.slice(1)
document.getElementById('content').innerHTML = decodeURIComponent(hash)Secure Patterns
Use textContent Instead of innerHTML
// SAFE
document.getElementById('output').textContent = userInputLet React Handle Encoding
// SAFE - React auto-escapes
function Comment({ content }) {
return {content}
}Sanitize When HTML Is Needed
import DOMPurify from 'dompurify'function RichContent({ html }) {
return (
)
}Use Trusted Markdown Libraries
import { marked } from 'marked'
import DOMPurify from 'dompurify'function MarkdownPreview({ markdown }) {
const html = DOMPurify.sanitize(marked.parse(markdown))
return
}Detection Patterns
Red Flags in AI Code
| Pattern | Risk |
|---|
dangerouslySetInnerHTML | High - Review every instance |
|---|
innerHTML = | Critical - Almost always XSS |
|---|
document.write() | Critical - Legacy XSS vector |
|---|
outerHTML = | Critical - XSS vector |
|---|
insertAdjacentHTML() | High - XSS if user input |
|---|
Search Your Codebase
grep -rn "dangerouslySetInnerHTML\innerHTML\
outerHTML" --include="*.tsx" --include="*.jsx" src/Framework-Specific Guidance
Next.js
Next.js auto-escapes in JSX, but watch for:
- API routes returning HTML
- getServerSideProps passing raw HTML
- Client components using dangerouslySetInnerHTML
React
React is safe by default for JSX expressions. Danger zones:
- dangerouslySetInnerHTML
- ref-based DOM manipulation
- Third-party components that accept HTML
Vue
Vue's v-html directive is equivalent to dangerouslySetInnerHTML:
Content Security Policy
Add CSP as a defense layer:
// next.config.js
const securityHeaders = [
{
key: 'Content-Security-Policy',
value: "default-src 'self'; script-src 'self'"
}
]CSP blocks inline scripts even if XSS exists.
Testing for XSS
Manual Test Payloads
Try these in input fields:
Automated Scanning
ShipReady detects dangerouslySetInnerHTML usage and traces data flow to identify vulnerable patterns.
The Bottom Line
Modern frameworks like React protect against XSS by default—but AI tools frequently bypass these protections with dangerouslySetInnerHTML and direct DOM manipulation.
Default to framework escaping. Sanitize when HTML is needed. Never trust user input.