一键导入
perseus-client
Client-side security analysis (DOM XSS, React/Vue/Angular, SSR, prototype pollution)
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Client-side security analysis (DOM XSS, React/Vue/Angular, SSR, prototype pollution)
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when you want to run a full, automated penetration test from start to finish (Scan -> Audit -> Exploit -> Report)
Use when starting a security conversation to understand the Perseus methodology
Use when analyzing components for vulnerabilities (Phase 2 - Parallel Analysis)
Use when verifying vulnerabilities with Dynamic Exploit Generation (Phase 3)
Use when generating the final executive security report (Phase 4)
Run all specialist deep-dive skills in parallel for comprehensive analysis
| name | perseus-client |
| description | Client-side security analysis (DOM XSS, React/Vue/Angular, SSR, prototype pollution) |
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.
| 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() |
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.
| 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 |
deliverables/engagement_profile.md before active runtime testing.PRODUCTION_SAFE when mode is not specified.| 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 |
deliverables/engagement_profile.md.deliverables/verification_scope.md when present.PRODUCTION_SAFE, prefer static and minimal observable checks only.React XSS Analyst:
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:
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:
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:
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:
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
Vue XSS Analyst:
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:
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:
Angular XSS Analyst:
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:
Source Identification Agent:
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:
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:
URL Scheme Analyst:
Patterns:
// React
<a href={url}> // If url = "javascript:..."
<iframe src={url}>
// Check validation:
if (!url.startsWith('https://')) { /* reject */ }
Pollution Source Analyst:
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:
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:
PostMessage Receiver Analyst:
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:
Patterns:
// VULNERABLE - Sending to any origin
parent.postMessage(sensitiveData, '*');
// VULNERABLE - Token in message
iframe.contentWindow.postMessage({ token: authToken }, '*');
Storage Security Analyst:
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:
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
| Attack | Safe Test Payload | Verification |
|---|---|---|
| DOM XSS | #<img src=x onerror=alert(1)> | 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 |
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 onerror=alert(document.cookie)>"
Impact: Full XSS - can steal cookies, perform actions as user
Remediation:
import DOMPurify from 'dompurify';
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(comment.body) }} />
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}%'`);
}
Severity: High
Location: middleware.ts:8
| 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* |
**Next Step:** DOM XSS findings can be verified with browser testing.