Security best practices and vulnerability prevention. Input validation, authentication, secrets management, OWASP top 10. Triggers: security, auth, authentication, secrets, credentials, vulnerability, injection, XSS, CSRF, rate-limit.
From kernelnpx claudepluginhub ariaxhan/kernel-claude --plugin kernelThis skill is limited to using the following tools:
reference/security-research.mdDesigns and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
<core_principles>
<secrets_management>
// BAD: Hardcoded secrets
const apiKey = "sk-proj-xxxxx" // NEVER
// GOOD: Environment variables
const apiKey = process.env.OPENAI_API_KEY
if (!apiKey) throw new Error('OPENAI_API_KEY not configured')
Checklist before commit:
<input_validation>
import { z } from 'zod'
const CreateUserSchema = z.object({
email: z.string().email(),
name: z.string().min(1).max(100),
age: z.number().int().min(0).max(150)
})
export async function createUser(input: unknown) {
const validated = CreateUserSchema.parse(input)
return await db.users.create(validated)
}
// File upload validation
function validateFileUpload(file: File) {
const maxSize = 5 * 1024 * 1024 // 5MB
if (file.size > maxSize) throw new Error('File too large')
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
if (!allowedTypes.includes(file.type)) throw new Error('Invalid file type')
const allowedExtensions = ['.jpg', '.jpeg', '.png', '.gif']
const ext = file.name.toLowerCase().match(/\.[^.]+$/)?.[0]
if (!ext || !allowedExtensions.includes(ext)) throw new Error('Invalid extension')
}
</input_validation>
<sql_injection>
// BAD: String concatenation
const query = `SELECT * FROM users WHERE email = '${userEmail}'` // NEVER
// GOOD: Parameterized queries
const { data } = await supabase
.from('users')
.select('*')
.eq('email', userEmail)
// Or with raw SQL
await db.query('SELECT * FROM users WHERE email = $1', [userEmail])
</sql_injection>
<xss_prevention>
import DOMPurify from 'isomorphic-dompurify'
// ALWAYS sanitize user-provided HTML
function renderUserContent(html: string) {
const clean = DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p'],
ALLOWED_ATTR: []
})
return <div dangerouslySetInnerHTML={{ __html: clean }} />
}
// Content Security Policy
const securityHeaders = [
{
key: 'Content-Security-Policy',
value: `
default-src 'self';
script-src 'self' 'unsafe-eval' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
connect-src 'self' https://api.example.com;
`.replace(/\s{2,}/g, ' ').trim()
}
]
</xss_prevention>
<authentication> ```typescript // BAD: localStorage (vulnerable to XSS) localStorage.setItem('token', token) // NEVER// GOOD: httpOnly cookies
res.setHeader('Set-Cookie',
token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600)
```typescript
// Authorization check
export async function deleteUser(userId: string, requesterId: string) {
const requester = await db.users.findUnique({ where: { id: requesterId } })
if (requester.role !== 'admin') {
return NextResponse.json({ error: 'Unauthorized' }, { status: 403 })
}
await db.users.delete({ where: { id: userId } })
}
-- Row Level Security (Supabase)
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users view own data"
ON users FOR SELECT
USING (auth.uid() = id);
</authentication>
<csrf_protection>
import { csrf } from '@/lib/csrf'
export async function POST(request: Request) {
const token = request.headers.get('X-CSRF-Token')
if (!csrf.verify(token)) {
return NextResponse.json({ error: 'Invalid CSRF token' }, { status: 403 })
}
// Process request
}
// SameSite cookies prevent CSRF
res.setHeader('Set-Cookie',
`session=${sessionId}; HttpOnly; Secure; SameSite=Strict`)
</csrf_protection>
<rate_limiting>
import rateLimit from 'express-rate-limit'
// General API rate limit
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // 100 requests per window
message: 'Too many requests'
})
// Stricter limit for expensive operations
const searchLimiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 10, // 10 requests per minute
})
app.use('/api/', limiter)
app.use('/api/search', searchLimiter)
</rate_limiting>
<error_handling>
// BAD: Exposing internals
catch (error) {
return NextResponse.json({
error: error.message,
stack: error.stack // NEVER
}, { status: 500 })
}
// GOOD: Generic messages
catch (error) {
console.error('Internal error:', error) // Log for debugging
return NextResponse.json({
error: 'An error occurred. Please try again.'
}, { status: 500 })
}
// BAD: Logging sensitive data
console.log('User login:', { email, password }) // NEVER
// GOOD: Redact sensitive fields
console.log('User login:', { email, userId })
</error_handling>
<owasp_awareness> Top vulnerabilities to prevent:
<pre_deployment_checklist> Before ANY production deployment:
<supply_chain>
<!-- Updated 2026-03-30: Claude Code best practices, OWASP supply chain guidance -->AI-generated code introduces supply chain risks beyond traditional OWASP top 10:
npm audit / pip audit / cargo audit on every PR,
not just on release. CI gate should block merge on HIGH/CRITICAL findings.<prompt_injection>
<!-- Updated 2026-03-30: Anthropic prompt engineering guide, agentic security research -->When building AI-integrated features, prevent prompt injection:
<anti_patterns>