JavaScript security best practices and vulnerability prevention.
Detects and fixes JavaScript security vulnerabilities like XSS, CSRF, and prototype pollution. Triggers when reviewing code that uses innerHTML, handles user input, or manages authentication tokens.
/plugin marketplace add pluginagentmarketplace/custom-plugin-javascript/plugin install javascript-developer-plugin@pluginagentmarketplace-javascriptThis skill inherits all available tools. When active, it can use any tool Claude has access to.
assets/config.yamlassets/schema.jsonreferences/GUIDE.mdreferences/PATTERNS.mdscripts/validate.py// DANGEROUS - Never do this
element.innerHTML = userInput;
// SAFE - Use textContent
element.textContent = userInput;
// SAFE - Sanitize HTML
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);
// SAFE - Create elements
const div = document.createElement('div');
div.textContent = userInput;
parent.appendChild(div);
// Server-side validation is required
// Client-side is for UX only
function validateEmail(email) {
const pattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return pattern.test(email);
}
function sanitizeInput(input) {
return input
.trim()
.replace(/[<>]/g, ''); // Basic, use library for real apps
}
// Use schema validation
import { z } from 'zod';
const UserSchema = z.object({
email: z.string().email(),
age: z.number().min(0).max(150)
});
UserSchema.parse(userData); // Throws if invalid
<!-- In HTML head or HTTP header -->
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' https://trusted.com;
style-src 'self' 'unsafe-inline';">
// NEVER store sensitive data in localStorage
// Use httpOnly cookies for tokens
// If you must use localStorage:
// - Don't store tokens
// - Don't store PII
// - Encrypt if necessary
// Secure cookie settings
document.cookie = 'token=abc; Secure; HttpOnly; SameSite=Strict';
// Include CSRF token in requests
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
fetch('/api/action', {
method: 'POST',
headers: {
'X-CSRF-Token': csrfToken,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
# Audit dependencies
npm audit
# Fix vulnerabilities
npm audit fix
# Check specific package
npm audit --package-lock-only
# Use Snyk for deeper analysis
npx snyk test
| Vulnerability | Prevention |
|---|---|
| XSS | Use textContent, sanitize |
| CSRF | Use tokens, SameSite cookies |
| Injection | Parameterized queries |
| Prototype pollution | Freeze prototypes |
| Open redirect | Validate URLs |
// Vulnerable
function merge(target, source) {
for (const key in source) {
target[key] = source[key]; // Can pollute __proto__
}
}
// Safe
function safeMerge(target, source) {
for (const key of Object.keys(source)) {
if (key === '__proto__' || key === 'constructor') continue;
target[key] = source[key];
}
}
// Or use Object.assign / spread
const merged = { ...target, ...source };
// Log security events
window.addEventListener('securitypolicyviolation', (e) => {
console.error('CSP violation:', e.blockedURI);
});
// Check for XSS vectors
const testInput = '<script>alert(1)</script>';
// If this executes, you have XSS
// Store in memory, not localStorage
let accessToken = null;
async function login(credentials) {
const response = await fetch('/api/login', {
method: 'POST',
credentials: 'include', // For httpOnly refresh token
body: JSON.stringify(credentials)
});
const { accessToken: token } = await response.json();
accessToken = token; // Memory only
}
// Refresh before expiry
async function refreshToken() {
const response = await fetch('/api/refresh', {
credentials: 'include'
});
const { accessToken: token } = await response.json();
accessToken = token;
}
function isSafeRedirect(url) {
try {
const parsed = new URL(url, window.location.origin);
return parsed.origin === window.location.origin;
} catch {
return false;
}
}
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.