Security best practices, OWASP compliance, authentication patterns, and vulnerability prevention
/plugin marketplace add Primadetaautomation/claude-dev-toolkit/plugin install claude-dev-toolkit@primadata-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
scripts/security-scan.shThis skill provides comprehensive security guidance following OWASP standards and industry best practices. It ensures secure code development and vulnerability prevention.
SEC-1: Input Validation (CRITICAL)
// ✅ GOOD - Validate at boundaries
import { z } from 'zod';
const userSchema = z.object({
email: z.string().email().max(255),
password: z.string().min(8).max(128),
name: z.string().min(1).max(100).regex(/^[a-zA-Z\s]+$/),
});
function createUser(input: unknown) {
// Validation happens at system boundary
const validated = userSchema.parse(input);
return userService.create(validated);
}
// ❌ BAD - No validation
function createUser(input: any) {
return userService.create(input); // Unsafe!
}
SEC-2: Output Sanitization (CRITICAL)
import DOMPurify from 'isomorphic-dompurify';
// ✅ GOOD - Sanitize before rendering
function displayUserContent(html: string) {
const clean = DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['p', 'br', 'strong', 'em'],
ALLOWED_ATTR: []
});
return <div dangerouslySetInnerHTML={{ __html: clean }} />;
}
// ❌ BAD - XSS vulnerability
function displayUserContent(html: string) {
return <div dangerouslySetInnerHTML={{ __html: html }} />; // XSS!
}
SEC-3: Secrets Management (CRITICAL)
// ✅ GOOD - Environment variables
const config = {
apiKey: process.env.API_KEY,
dbPassword: process.env.DB_PASSWORD,
jwtSecret: process.env.JWT_SECRET,
};
// Validate at startup
if (!config.apiKey || !config.dbPassword || !config.jwtSecret) {
throw new Error('Missing required environment variables');
}
// ❌ BAD - Hardcoded secrets
const config = {
apiKey: 'sk-1234567890abcdef', // NEVER DO THIS!
dbPassword: 'admin123',
jwtSecret: 'my-secret-key',
};
SEC-4: Never Log Sensitive Data (CRITICAL)
// ✅ GOOD - Redact sensitive fields
logger.info('User login attempt', {
userId: user.id,
email: user.email,
// password is NOT logged
});
// ❌ BAD - Logging sensitive data
logger.info('User login', {
email: user.email,
password: user.password, // NEVER LOG PASSWORDS!
creditCard: user.creditCard, // NEVER LOG PII!
});
SEC-5: Authentication Best Practices
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
// ✅ GOOD - Secure password hashing
async function hashPassword(password: string): Promise<string> {
const saltRounds = 12;
return bcrypt.hash(password, saltRounds);
}
async function verifyPassword(password: string, hash: string): Promise<boolean> {
return bcrypt.compare(password, hash);
}
// ✅ GOOD - Secure JWT generation
function generateToken(userId: string): string {
return jwt.sign(
{ userId },
process.env.JWT_SECRET!,
{
expiresIn: '1h',
algorithm: 'HS256',
}
);
}
// ❌ BAD - Plain text password storage
function savePassword(password: string) {
db.query('INSERT INTO users (password) VALUES (?)', [password]); // NEVER!
}
SEC-6: SQL Injection Prevention
// ✅ GOOD - Parameterized queries
async function getUserByEmail(email: string) {
return db.query(
'SELECT * FROM users WHERE email = $1',
[email] // Parameterized
);
}
// ❌ BAD - String concatenation (SQL injection!)
async function getUserByEmail(email: string) {
return db.query(
`SELECT * FROM users WHERE email = '${email}'` // SQL Injection!
);
}
SEC-7: CSRF Protection
import csrf from 'csurf';
import cookieParser from 'cookie-parser';
// ✅ GOOD - CSRF tokens
app.use(cookieParser());
app.use(csrf({ cookie: true }));
app.get('/form', (req, res) => {
res.render('form', { csrfToken: req.csrfToken() });
});
app.post('/submit', (req, res) => {
// CSRF token automatically verified
res.send('Data processed');
});
SEC-8: Secure Headers
import helmet from 'helmet';
// ✅ GOOD - Security headers
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true,
},
}));
// Cookie security
app.use(session({
secret: process.env.SESSION_SECRET!,
cookie: {
secure: true, // HTTPS only
httpOnly: true, // No JavaScript access
sameSite: 'strict', // CSRF protection
maxAge: 3600000, // 1 hour
},
}));
Before deploying to production:
See companion files:
owasp-guide.md - Detailed OWASP Top 10 implementationsauth-patterns.md - JWT, OAuth2, MFA implementationsencryption-guide.md - Encryption at rest and in transitSee scripts directory:
scripts/security-scan.sh - Run comprehensive security scanscripts/dependency-check.sh - Check for vulnerable dependenciesscripts/secret-scan.sh - Scan for exposed secretssecurity-specialist:
senior-fullstack-developer:
qa-testing-engineer:
// Vulnerable
function renderHTML(userInput: string) {
document.innerHTML = userInput; // XSS!
}
// Fixed
import DOMPurify from 'isomorphic-dompurify';
function renderHTML(userInput: string) {
const clean = DOMPurify.sanitize(userInput);
document.innerHTML = clean;
}
// Vulnerable
app.get('/file/:filename', (req, res) => {
const file = path.join(__dirname, req.params.filename);
res.sendFile(file); // Path traversal: ../../etc/passwd
});
// Fixed
app.get('/file/:filename', (req, res) => {
const filename = path.basename(req.params.filename); // Remove path
const file = path.join(__dirname, 'uploads', filename);
// Ensure file is within allowed directory
if (!file.startsWith(path.join(__dirname, 'uploads'))) {
return res.status(403).send('Forbidden');
}
res.sendFile(file);
});
// Vulnerable
function findUser(username: string) {
return db.users.findOne({ username }); // Can inject: {$ne: null}
}
// Fixed
function findUser(username: string) {
if (typeof username !== 'string') {
throw new ValidationError('Username must be a string');
}
return db.users.findOne({ username });
}
If a security vulnerability is discovered:
Version 1.0.0 | OWASP Top 10 Compliant | GDPR Aware
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.