Perseus Client-Side Specialist
Context & Authorization
IMPORTANT: This skill performs client-side security analysis on the user's own codebase. This is defensive security testing to find browser-side vulnerabilities.
Authorization: The user owns this codebase and has explicitly requested this specialized analysis.
Multi-Framework Support
| Framework |
Versions |
Special Considerations |
| React |
16+, 18+, 19+ |
RSC, Server Actions, JSX injection |
| Next.js |
12+, 13+, 14+, 15+ |
App Router, Server Components, Middleware |
| Vue |
2, 3 |
v-html, template injection |
| Angular |
12+ |
bypassSecurityTrust*, template injection |
| Svelte |
3, 4, 5 |
{@html}, SSR |
| SolidJS |
1.x |
innerHTML, SSR |
| Vanilla JS |
ES6+ |
Direct DOM manipulation |
| jQuery |
All |
.html(), .append() |
Overview
This specialist skill performs deep client-side JavaScript security analysis, focusing on vulnerabilities in modern frameworks including React, Vue, Angular, and SSR frameworks.
When to Use: After /scan identifies significant client-side JavaScript, SPAs, or SSR applications.
Goal: Find DOM-based XSS, prototype pollution, and framework-specific vulnerabilities.
Engagement Mode Compatibility
| Mode |
Specialist Behavior |
PRODUCTION_SAFE |
Code-level and rendering-path analysis, minimal runtime probes |
STAGING_ACTIVE |
Controlled browser-side verification with throttling |
LAB_FULL |
Expanded dynamic client attack-surface validation |
LAB_RED_TEAM |
End-to-end client attack-chain simulation in isolated lab |
Safety Gates (Required)
- Read
deliverables/engagement_profile.md before active runtime testing.
- Default to
PRODUCTION_SAFE when mode is not specified.
- Enforce kill-switch thresholds and stop on instability.
- Never execute persistent or user-impacting payloads in production.
Client-Side Risks Covered
| Risk |
Description |
Impact |
| DOM XSS |
Client-side script injection |
Account takeover, data theft |
| React XSS |
Unsafe HTML rendering, href injection |
XSS via JSX |
| SSR Injection |
Server component injection |
RCE, data leak |
| Prototype Pollution |
Object prototype manipulation |
XSS, DoS, logic bypass |
| PostMessage Abuse |
Cross-origin message issues |
Data leakage, XSS |
| DOM Clobbering |
HTML overwriting JS variables |
XSS, security bypass |
| Client Storage |
Sensitive data exposure |
Session hijacking |
Execution Instructions
Step 0: Mode & Scope Alignment
- Load mode/scope/limits from
deliverables/engagement_profile.md.
- Respect
deliverables/verification_scope.md when present.
- In
PRODUCTION_SAFE, prefer static and minimal observable checks only.
Phase 1: React/Next.js Security Analysis (5 Parallel Agents)
React XSS Analyst:
- "Find React-specific XSS vectors."
Vulnerable Patterns:
// VULNERABLE - Dangerous HTML rendering
<div dangerouslySetInnerHTML={{ __html: userInput }} />
// VULNERABLE - javascript: in href
<a href={userUrl}>Click</a>
// Attack: userUrl = "javascript:alert(1)"
// VULNERABLE - Dynamic component
const Component = components[userInput];
return <Component />;
// VULNERABLE - Spread props from user
<div {...userProps} />
// Attack: userProps = { dangerouslySetInnerHTML: { __html: '<script>...' } }
Next.js Server Component Analyst:
- "Analyze Next.js App Router and Server Components for security issues."
Patterns:
// VULNERABLE - SQL in Server Component
async function UserPage({ params }) {
const user = await db.query(`SELECT * FROM users WHERE id = ${params.id}`);
return <div>{user.name}</div>;
}
// VULNERABLE - Exposing secrets to client
// In Server Component that passes to Client Component
<ClientComponent apiKey={process.env.SECRET_KEY} />
// VULNERABLE - Unvalidated redirect
import { redirect } from 'next/navigation';
redirect(userInput);
Next.js Server Actions Analyst:
- "Analyze Server Actions for security issues."
Patterns:
// VULNERABLE - No auth check in Server Action
'use server'
async function deleteUser(userId: string) {
await db.users.delete(userId); // No auth check!
}
// VULNERABLE - SQL injection in Server Action
'use server'
async function searchUsers(query: string) {
return db.query(`SELECT * FROM users WHERE name LIKE '%${query}%'`);
}
// VULNERABLE - CSRF (if custom implementation)
// Server Actions have built-in CSRF protection, but check custom forms
Next.js Middleware Analyst:
- "Analyze Next.js middleware for security issues."
Patterns:
// VULNERABLE - Open redirect
export function middleware(request: NextRequest) {
const url = request.nextUrl.searchParams.get('redirect');
return NextResponse.redirect(url); // No validation!
}
// VULNERABLE - Auth bypass via header manipulation
export function middleware(request: NextRequest) {
if (request.headers.get('x-admin') === 'true') {
return NextResponse.next(); // Spoofable!
}
}
React State Exposure Analyst:
- "Check for sensitive data exposure in React state/props."
Patterns:
// VULNERABLE - Secrets in client state
const [config, setConfig] = useState({
apiKey: 'sk-xxx', // Exposed in React DevTools
adminToken: '...'
});
// VULNERABLE - SSR hydration mismatch leaking data
// Server renders with user data, client sees different user's data
Phase 2: Vue Security Analysis (3 Parallel Agents)
Vue XSS Analyst:
- "Find Vue-specific XSS vectors."
Patterns:
<!-- VULNERABLE - v-html with user input -->
<div v-html="userContent"></div>
<!-- VULNERABLE - Dynamic component -->
<component :is="userComponent" />
<!-- VULNERABLE - Template compilation -->
<script>
new Vue({
template: userTemplate // If user controls this
});
</script>
<!-- VULNERABLE - javascript: in :href -->
<a :href="userUrl">Link</a>
Nuxt.js Analyst:
- "Analyze Nuxt.js specific security issues."
Patterns:
// VULNERABLE - Nuxt 3 server routes
export default defineEventHandler((event) => {
const id = getQuery(event).id;
return db.query(`SELECT * FROM items WHERE id = ${id}`);
});
// VULNERABLE - Exposing secrets
// nuxt.config.ts
runtimeConfig: {
public: {
secretKey: process.env.SECRET // Exposed to client!
}
}
Vue State Analyst:
- "Check Vuex/Pinia state for sensitive data exposure."
Phase 3: Angular Security Analysis (2 Parallel Agents)
Angular XSS Analyst:
- "Find Angular-specific XSS vectors."
Patterns:
// VULNERABLE - bypassSecurityTrust*
constructor(private sanitizer: DomSanitizer) {}
getHtml() {
return this.sanitizer.bypassSecurityTrustHtml(userInput);
}
// VULNERABLE - Template injection
@Component({
template: userTemplate // If user controls this
})
// VULNERABLE - innerHTML binding
<div [innerHTML]="userContent"></div>
Angular SSR Analyst:
- "Analyze Angular Universal for security issues."
Phase 4: DOM XSS Analysis (4 Parallel Agents)
Source Identification Agent:
- "Identify all DOM XSS sources across frameworks."
Sources:
// URL-based sources
location.hash
location.search
location.href
document.URL
document.documentURI
document.referrer
// Storage sources
localStorage.getItem()
sessionStorage.getItem()
document.cookie
// Message sources
window.addEventListener('message', (e) => e.data)
// Framework-specific
// React: props from URL, useSearchParams()
// Next.js: searchParams, params
// Vue: $route.query, $route.params
Sink Identification Agent:
- "Identify all DOM XSS sinks across frameworks."
Sinks:
// Direct sinks
element.innerHTML = data
element.outerHTML = data
document.write(data)
document.writeln(data)
// jQuery sinks
$(selector).html(data)
$(selector).append(data)
$(data) // If data contains HTML
// Eval sinks
eval(data)
new Function(data)
setTimeout(data, 0)
setInterval(data, 0)
// Location sinks
location.href = data
location.assign(data)
location.replace(data)
window.open(data)
// Framework-specific already covered above
Flow Tracer Agent:
- "Trace data flow from sources to sinks."
URL Scheme Analyst:
- "Check for javascript: and data: URL injection."
Patterns:
// React
<a href={url}> // If url = "javascript:..."
<iframe src={url}>
// Check validation:
if (!url.startsWith('https://')) { /* reject */ }
Phase 5: Prototype Pollution Analysis (3 Parallel Agents)
Pollution Source Analyst:
- "Find prototype pollution entry points."
Patterns:
// VULNERABLE - Deep merge without __proto__ check
function merge(target, source) {
for (let key in source) {
if (typeof source[key] === 'object') {
target[key] = merge(target[key] || {}, source[key]);
} else {
target[key] = source[key]; // Can set __proto__
}
}
}
// VULNERABLE - URL params to object
const params = Object.fromEntries(new URLSearchParams(location.search));
// Attack: ?__proto__[isAdmin]=true
// VULNERABLE libraries (check versions)
// lodash < 4.17.12
// jQuery < 3.4.0
// minimist < 1.2.3
Gadget Finder Agent:
- "Find prototype pollution gadgets."
Patterns:
// GADGET - Property access on polluted prototype
if (options.isAdmin) { // Can be polluted
showAdminPanel();
}
// GADGET - HTML attribute setting
element.setAttribute(key, config[key]); // key from polluted proto
Library Analyst:
- "Check for vulnerable libraries."
Phase 6: PostMessage Analysis (2 Parallel Agents)
PostMessage Receiver Analyst:
- "Find all postMessage listeners."
Patterns:
// VULNERABLE - No origin check
window.addEventListener('message', (e) => {
eval(e.data.code); // RCE via any origin
});
// VULNERABLE - Weak origin check
window.addEventListener('message', (e) => {
if (e.origin.includes('trusted.com')) { // trusted.com.evil.com bypasses
// ...
}
});
// SAFE
window.addEventListener('message', (e) => {
if (e.origin !== 'https://trusted.com') return;
// ...
});
PostMessage Sender Analyst:
- "Check postMessage sends for data leakage."
Patterns:
// VULNERABLE - Sending to any origin
parent.postMessage(sensitiveData, '*');
// VULNERABLE - Token in message
iframe.contentWindow.postMessage({ token: authToken }, '*');
Phase 7: Client Storage & Secrets (2 Parallel Agents)
Storage Security Analyst:
- "Analyze localStorage/sessionStorage usage."
Issues:
// VULNERABLE - Token in localStorage (XSS accessible)
localStorage.setItem('authToken', token);
// VULNERABLE - Sensitive data persisted
localStorage.setItem('user', JSON.stringify({
ssn: '123-45-6789',
creditCard: '4111...'
}));
Client Secret Analyst:
- "Find secrets in client-side code."
Patterns:
// Secrets in JS bundles
const API_KEY = 'sk-xxx';
const STRIPE_SECRET = 'sk_live_xxx';
// Check .env files exposed
// Check webpack/vite config for DefinePlugin exposure
Safe Payload Reference
| Attack |
Safe Test Payload |
Verification |
| DOM XSS |
#<img src=x> |
Alert box appears |
| React href |
javascript:alert(1) |
Alert on click |
| Prototype Pollution |
?__proto__[test]=polluted |
({}).test === 'polluted' |
| PostMessage |
Send from different origin |
Check if processed |
Output Requirements
Create deliverables/client_side_analysis.md:
# Client-Side Security Analysis
## Summary
| Category | Issues Found | Critical | High | Medium |
|----------|--------------|----------|------|--------|
| React/Next.js XSS | X | Y | Z | W |
| Vue XSS | X | Y | Z | W |
| Angular XSS | X | Y | Z | W |
| DOM XSS | X | Y | Z | W |
| Server Components | X | Y | Z | W |
| Prototype Pollution | X | Y | Z | W |
| PostMessage | X | Y | Z | W |
| Client Storage | X | Y | Z | W |
## Framework Detected
- Primary: [React 18, Next.js 14, Vue 3, etc.]
- SSR: [Yes/No]
- Build Tool: [Vite, Webpack, Turbopack]
## Critical Findings
### [CLIENT-001] XSS via dangerouslySetInnerHTML
**Severity:** Critical
**Framework:** React
**Location:** `components/Comment.tsx:23`
**Vulnerable Code:**
```jsx
<div dangerouslySetInnerHTML={{ __html: comment.body }} />
Attack:
comment.body = "<img src=x
Impact: Full XSS - can steal cookies, perform actions as user
Remediation:
import DOMPurify from 'dompurify';
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(comment.body) }} />
[CLIENT-002] SQL Injection in Server Action
Severity: Critical
Framework: Next.js 14
Location: app/actions/search.ts:12
Vulnerable Code:
'use server'
async function searchProducts(query: string) {
return db.query(`SELECT * FROM products WHERE name LIKE '%${query}%'`);
}
[CLIENT-003] Open Redirect in Next.js Middleware
Severity: High
Location: middleware.ts:8
Framework Security Matrix
| Framework |
Auto-Escape |
Common Pitfalls |
| React |
Yes (JSX) |
dangerouslySetInnerHTML, href |
| Next.js |
Yes |
Server Actions auth, middleware |
| Vue |
Yes |
v-html, :href |
| Angular |
Yes |
bypassSecurityTrust* |
Recommendations
- Sanitize all user content with DOMPurify before rendering
- Validate URLs before using in href/src attributes
- Add authentication checks to all Server Actions
- Validate redirect URLs in middleware
- Move tokens from localStorage to HttpOnly cookies
**Next Step:** DOM XSS findings can be verified with browser testing.
---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/kaivyy) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-11 -->
1---2name: perseus-client3description: Client-side security analysis (DOM XSS, React/Vue/Angular, SSR, prototype pollution) Use when this capability is needed.4---56# Perseus Client-Side Specialist78## Context & Authorization910**IMPORTANT:** This skill performs client-side security analysis on the **user's own codebase**. This is defensive security testing to find browser-side vulnerabilities.1112**Authorization:** The user owns this codebase and has explicitly requested this specialized analysis.1314---1516## Multi-Framework Support1718| Framework | Versions | Special Considerations |19|-----------|----------|----------------------|20| React | 16+, 18+, 19+ | RSC, Server Actions, JSX injection |21| Next.js | 12+, 13+, 14+, 15+ | App Router, Server Components, Middleware |22| Vue | 2, 3 | v-html, template injection |23| Angular | 12+ | bypassSecurityTrust*, template injection |24| Svelte | 3, 4, 5 | {@html}, SSR |25| SolidJS | 1.x | innerHTML, SSR |26| Vanilla JS | ES6+ | Direct DOM manipulation |27| jQuery | All | .html(), .append() |2829---3031## Overview3233This specialist skill performs deep client-side JavaScript security analysis, focusing on vulnerabilities in modern frameworks including React, Vue, Angular, and SSR frameworks.3435**When to Use:** After `/scan` identifies significant client-side JavaScript, SPAs, or SSR applications.3637**Goal:** Find DOM-based XSS, prototype pollution, and framework-specific vulnerabilities.3839## Engagement Mode Compatibility4041| Mode | Specialist Behavior |42|------|---------------------|43| `PRODUCTION_SAFE` | Code-level and rendering-path analysis, minimal runtime probes |44| `STAGING_ACTIVE` | Controlled browser-side verification with throttling |45| `LAB_FULL` | Expanded dynamic client attack-surface validation |46| `LAB_RED_TEAM` | End-to-end client attack-chain simulation in isolated lab |4748## Safety Gates (Required)49501. Read `deliverables/engagement_profile.md` before active runtime testing.512. Default to `PRODUCTION_SAFE` when mode is not specified.523. Enforce kill-switch thresholds and stop on instability.534. Never execute persistent or user-impacting payloads in production.5455## Client-Side Risks Covered5657| Risk | Description | Impact |58|------|-------------|--------|59| DOM XSS | Client-side script injection | Account takeover, data theft |60| React XSS | Unsafe HTML rendering, href injection | XSS via JSX |61| SSR Injection | Server component injection | RCE, data leak |62| Prototype Pollution | Object prototype manipulation | XSS, DoS, logic bypass |63| PostMessage Abuse | Cross-origin message issues | Data leakage, XSS |64| DOM Clobbering | HTML overwriting JS variables | XSS, security bypass |65| Client Storage | Sensitive data exposure | Session hijacking |6667## Execution Instructions6869### Step 0: Mode & Scope Alignment7071- Load mode/scope/limits from `deliverables/engagement_profile.md`.72- Respect `deliverables/verification_scope.md` when present.73- In `PRODUCTION_SAFE`, prefer static and minimal observable checks only.7475### Phase 1: React/Next.js Security Analysis (5 Parallel Agents)76771. **React XSS Analyst:**78 * "Find React-specific XSS vectors."7980 **Vulnerable Patterns:**81 ```jsx82 // VULNERABLE - Dangerous HTML rendering83 <div dangerouslySetInnerHTML={{ __html: userInput }} />8485 // VULNERABLE - javascript: in href86 <a href={userUrl}>Click</a>87 // Attack: userUrl = "javascript:alert(1)"8889 // VULNERABLE - Dynamic component90 const Component = components[userInput];91 return <Component />;9293 // VULNERABLE - Spread props from user94 <div {...userProps} />95 // Attack: userProps = { dangerouslySetInnerHTML: { __html: '<script>...' } }96 ```97982. **Next.js Server Component Analyst:**99 * "Analyze Next.js App Router and Server Components for security issues."100101 **Patterns:**102 ```typescript103 // VULNERABLE - SQL in Server Component104 async function UserPage({ params }) {105 const user = await db.query(`SELECT * FROM users WHERE id = ${params.id}`);106 return <div>{user.name}</div>;107 }108109 // VULNERABLE - Exposing secrets to client110 // In Server Component that passes to Client Component111 <ClientComponent apiKey={process.env.SECRET_KEY} />112113 // VULNERABLE - Unvalidated redirect114 import { redirect } from 'next/navigation';115 redirect(userInput);116 ```1171183. **Next.js Server Actions Analyst:**119 * "Analyze Server Actions for security issues."120121 **Patterns:**122 ```typescript123 // VULNERABLE - No auth check in Server Action124 'use server'125 async function deleteUser(userId: string) {126 await db.users.delete(userId); // No auth check!127 }128129 // VULNERABLE - SQL injection in Server Action130 'use server'131 async function searchUsers(query: string) {132 return db.query(`SELECT * FROM users WHERE name LIKE '%${query}%'`);133 }134135 // VULNERABLE - CSRF (if custom implementation)136 // Server Actions have built-in CSRF protection, but check custom forms137 ```1381394. **Next.js Middleware Analyst:**140 * "Analyze Next.js middleware for security issues."141142 **Patterns:**143 ```typescript144 // VULNERABLE - Open redirect145 export function middleware(request: NextRequest) {146 const url = request.nextUrl.searchParams.get('redirect');147 return NextResponse.redirect(url); // No validation!148 }149150 // VULNERABLE - Auth bypass via header manipulation151 export function middleware(request: NextRequest) {152 if (request.headers.get('x-admin') === 'true') {153 return NextResponse.next(); // Spoofable!154 }155 }156 ```1571585. **React State Exposure Analyst:**159 * "Check for sensitive data exposure in React state/props."160161 **Patterns:**162 ```jsx163 // VULNERABLE - Secrets in client state164 const [config, setConfig] = useState({165 apiKey: 'sk-xxx', // Exposed in React DevTools166 adminToken: '...'167 });168169 // VULNERABLE - SSR hydration mismatch leaking data170 // Server renders with user data, client sees different user's data171 ```172173### Phase 2: Vue Security Analysis (3 Parallel Agents)1741751. **Vue XSS Analyst:**176 * "Find Vue-specific XSS vectors."177178 **Patterns:**179 ```vue180 <!-- VULNERABLE - v-html with user input -->181 <div v-html="userContent"></div>182183 <!-- VULNERABLE - Dynamic component -->184 <component :is="userComponent" />185186 <!-- VULNERABLE - Template compilation -->187 <script>188 new Vue({189 template: userTemplate // If user controls this190 });191 </script>192193 <!-- VULNERABLE - javascript: in :href -->194 <a :href="userUrl">Link</a>195 ```1961972. **Nuxt.js Analyst:**198 * "Analyze Nuxt.js specific security issues."199200 **Patterns:**201 ```typescript202 // VULNERABLE - Nuxt 3 server routes203 export default defineEventHandler((event) => {204 const id = getQuery(event).id;205 return db.query(`SELECT * FROM items WHERE id = ${id}`);206 });207208 // VULNERABLE - Exposing secrets209 // nuxt.config.ts210 runtimeConfig: {211 public: {212 secretKey: process.env.SECRET // Exposed to client!213 }214 }215 ```2162173. **Vue State Analyst:**218 * "Check Vuex/Pinia state for sensitive data exposure."219220### Phase 3: Angular Security Analysis (2 Parallel Agents)2212221. **Angular XSS Analyst:**223 * "Find Angular-specific XSS vectors."224225 **Patterns:**226 ```typescript227 // VULNERABLE - bypassSecurityTrust*228 constructor(private sanitizer: DomSanitizer) {}229230 getHtml() {231 return this.sanitizer.bypassSecurityTrustHtml(userInput);232 }233234 // VULNERABLE - Template injection235 @Component({236 template: userTemplate // If user controls this237 })238239 // VULNERABLE - innerHTML binding240 <div [innerHTML]="userContent"></div>241 ```2422432. **Angular SSR Analyst:**244 * "Analyze Angular Universal for security issues."245246### Phase 4: DOM XSS Analysis (4 Parallel Agents)2472481. **Source Identification Agent:**249 * "Identify all DOM XSS sources across frameworks."250251 **Sources:**252 ```javascript253 // URL-based sources254 location.hash255 location.search256 location.href257 document.URL258 document.documentURI259 document.referrer260261 // Storage sources262 localStorage.getItem()263 sessionStorage.getItem()264 document.cookie265266 // Message sources267 window.addEventListener('message', (e) => e.data)268269 // Framework-specific270 // React: props from URL, useSearchParams()271 // Next.js: searchParams, params272 // Vue: $route.query, $route.params273 ```2742752. **Sink Identification Agent:**276 * "Identify all DOM XSS sinks across frameworks."277278 **Sinks:**279 ```javascript280 // Direct sinks281 element.innerHTML = data282 element.outerHTML = data283 document.write(data)284 document.writeln(data)285286 // jQuery sinks287 $(selector).html(data)288 $(selector).append(data)289 $(data) // If data contains HTML290291 // Eval sinks292 eval(data)293 new Function(data)294 setTimeout(data, 0)295 setInterval(data, 0)296297 // Location sinks298 location.href = data299 location.assign(data)300 location.replace(data)301 window.open(data)302303 // Framework-specific already covered above304 ```3053063. **Flow Tracer Agent:**307 * "Trace data flow from sources to sinks."3083094. **URL Scheme Analyst:**310 * "Check for javascript: and data: URL injection."311312 **Patterns:**313 ```jsx314 // React315 <a href={url}> // If url = "javascript:..."316 <iframe src={url}>317318 // Check validation:319 if (!url.startsWith('https://')) { /* reject */ }320 ```321322### Phase 5: Prototype Pollution Analysis (3 Parallel Agents)3233241. **Pollution Source Analyst:**325 * "Find prototype pollution entry points."326327 **Patterns:**328 ```javascript329 // VULNERABLE - Deep merge without __proto__ check330 function merge(target, source) {331 for (let key in source) {332 if (typeof source[key] === 'object') {333 target[key] = merge(target[key] || {}, source[key]);334 } else {335 target[key] = source[key]; // Can set __proto__336 }337 }338 }339340 // VULNERABLE - URL params to object341 const params = Object.fromEntries(new URLSearchParams(location.search));342 // Attack: ?__proto__[isAdmin]=true343344 // VULNERABLE libraries (check versions)345 // lodash < 4.17.12346 // jQuery < 3.4.0347 // minimist < 1.2.3348 ```3493502. **Gadget Finder Agent:**351 * "Find prototype pollution gadgets."352353 **Patterns:**354 ```javascript355 // GADGET - Property access on polluted prototype356 if (options.isAdmin) { // Can be polluted357 showAdminPanel();358 }359360 // GADGET - HTML attribute setting361 element.setAttribute(key, config[key]); // key from polluted proto362 ```3633643. **Library Analyst:**365 * "Check for vulnerable libraries."366367### Phase 6: PostMessage Analysis (2 Parallel Agents)3683691. **PostMessage Receiver Analyst:**370 * "Find all postMessage listeners."371372 **Patterns:**373 ```javascript374 // VULNERABLE - No origin check375 window.addEventListener('message', (e) => {376 eval(e.data.code); // RCE via any origin377 });378379 // VULNERABLE - Weak origin check380 window.addEventListener('message', (e) => {381 if (e.origin.includes('trusted.com')) { // trusted.com.evil.com bypasses382 // ...383 }384 });385386 // SAFE387 window.addEventListener('message', (e) => {388 if (e.origin !== 'https://trusted.com') return;389 // ...390 });391 ```3923932. **PostMessage Sender Analyst:**394 * "Check postMessage sends for data leakage."395396 **Patterns:**397 ```javascript398 // VULNERABLE - Sending to any origin399 parent.postMessage(sensitiveData, '*');400401 // VULNERABLE - Token in message402 iframe.contentWindow.postMessage({ token: authToken }, '*');403 ```404405### Phase 7: Client Storage & Secrets (2 Parallel Agents)4064071. **Storage Security Analyst:**408 * "Analyze localStorage/sessionStorage usage."409410 **Issues:**411 ```javascript412 // VULNERABLE - Token in localStorage (XSS accessible)413 localStorage.setItem('authToken', token);414415 // VULNERABLE - Sensitive data persisted416 localStorage.setItem('user', JSON.stringify({417 ssn: '123-45-6789',418 creditCard: '4111...'419 }));420 ```4214222. **Client Secret Analyst:**423 * "Find secrets in client-side code."424425 **Patterns:**426 ```javascript427 // Secrets in JS bundles428 const API_KEY = 'sk-xxx';429 const STRIPE_SECRET = 'sk_live_xxx';430431 // Check .env files exposed432 // Check webpack/vite config for DefinePlugin exposure433 ```434435## Safe Payload Reference436437| Attack | Safe Test Payload | Verification |438|--------|-------------------|--------------|439| DOM XSS | `#<img src=x onerror=alert(1)>` | Alert box appears |440| React href | `javascript:alert(1)` | Alert on click |441| Prototype Pollution | `?__proto__[test]=polluted` | `({}).test === 'polluted'` |442| PostMessage | Send from different origin | Check if processed |443444## Output Requirements445446Create `deliverables/client_side_analysis.md`:447448```markdown449# Client-Side Security Analysis450451## Summary452| Category | Issues Found | Critical | High | Medium |453|----------|--------------|----------|------|--------|454| React/Next.js XSS | X | Y | Z | W |455| Vue XSS | X | Y | Z | W |456| Angular XSS | X | Y | Z | W |457| DOM XSS | X | Y | Z | W |458| Server Components | X | Y | Z | W |459| Prototype Pollution | X | Y | Z | W |460| PostMessage | X | Y | Z | W |461| Client Storage | X | Y | Z | W |462463## Framework Detected464- Primary: [React 18, Next.js 14, Vue 3, etc.]465- SSR: [Yes/No]466- Build Tool: [Vite, Webpack, Turbopack]467468## Critical Findings469470### [CLIENT-001] XSS via dangerouslySetInnerHTML471**Severity:** Critical472**Framework:** React473**Location:** `components/Comment.tsx:23`474475**Vulnerable Code:**476```jsx477<div dangerouslySetInnerHTML={{ __html: comment.body }} />478```479480**Attack:**481```482comment.body = "<img src=x onerror=alert(document.cookie)>"483```484485**Impact:** Full XSS - can steal cookies, perform actions as user486487**Remediation:**488```jsx489import DOMPurify from 'dompurify';490<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(comment.body) }} />491```492493---494495### [CLIENT-002] SQL Injection in Server Action496**Severity:** Critical497**Framework:** Next.js 14498**Location:** `app/actions/search.ts:12`499500**Vulnerable Code:**501```typescript502'use server'503async function searchProducts(query: string) {504 return db.query(`SELECT * FROM products WHERE name LIKE '%${query}%'`);505}506```507508---509510### [CLIENT-003] Open Redirect in Next.js Middleware511**Severity:** High512**Location:** `middleware.ts:8`513514---515516## Framework Security Matrix517518| Framework | Auto-Escape | Common Pitfalls |519|-----------|-------------|-----------------|520| React | Yes (JSX) | dangerouslySetInnerHTML, href |521| Next.js | Yes | Server Actions auth, middleware |522| Vue | Yes | v-html, :href |523| Angular | Yes | bypassSecurityTrust* |524525## Recommendations5261. Sanitize all user content with DOMPurify before rendering5272. Validate URLs before using in href/src attributes5283. Add authentication checks to all Server Actions5294. Validate redirect URLs in middleware5305. Move tokens from localStorage to HttpOnly cookies531```532533**Next Step:** DOM XSS findings can be verified with browser testing.534535---536> Converted and distributed by [TomeVault](https://tomevault.io/claim/kaivyy) — claim your Tome and manage your conversions.537<!-- tomevault:4.0:skill_md:2026-04-11 -->