Claude Agent Skill · by Affaan M

Security Review

The security-review skill provides developers with a comprehensive security checklist and code patterns to prevent vulnerabilities when implementing authenticat

Install
Terminal · npx
$npx skills add https://github.com/affaan-m/everything-claude-code --skill security-review
Works with Paperclip

How Security Review fits into a Paperclip company.

Security Review drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.

S
SaaS FactoryPaired

Pre-configured AI company — 18 agents, 18 skills, one-time purchase.

$27$59
Explore pack
Source file
SKILL.md495 lines
Expand
---name: security-reviewdescription: Use this skill when adding authentication, handling user input, working with secrets, creating API endpoints, or implementing payment/sensitive features. Provides comprehensive security checklist and patterns.origin: ECC--- # Security Review Skill This skill ensures all code follows security best practices and identifies potential vulnerabilities. ## When to Activate - Implementing authentication or authorization- Handling user input or file uploads- Creating new API endpoints- Working with secrets or credentials- Implementing payment features- Storing or transmitting sensitive data- Integrating third-party APIs ## Security Checklist ### 1. Secrets Management #### FAIL: NEVER Do This```typescriptconst apiKey = "sk-proj-xxxxx"  // Hardcoded secretconst dbPassword = "password123" // In source code``` #### PASS: ALWAYS Do This```typescriptconst apiKey = process.env.OPENAI_API_KEYconst dbUrl = process.env.DATABASE_URL // Verify secrets existif (!apiKey) {  throw new Error('OPENAI_API_KEY not configured')}``` #### Verification Steps- [ ] No hardcoded API keys, tokens, or passwords- [ ] All secrets in environment variables- [ ] `.env.local` in .gitignore- [ ] No secrets in git history- [ ] Production secrets in hosting platform (Vercel, Railway) ### 2. Input Validation #### Always Validate User Input```typescriptimport { z } from 'zod' // Define validation schemaconst CreateUserSchema = z.object({  email: z.string().email(),  name: z.string().min(1).max(100),  age: z.number().int().min(0).max(150)}) // Validate before processingexport async function createUser(input: unknown) {  try {    const validated = CreateUserSchema.parse(input)    return await db.users.create(validated)  } catch (error) {    if (error instanceof z.ZodError) {      return { success: false, errors: error.errors }    }    throw error  }}``` #### File Upload Validation```typescriptfunction validateFileUpload(file: File) {  // Size check (5MB max)  const maxSize = 5 * 1024 * 1024  if (file.size > maxSize) {    throw new Error('File too large (max 5MB)')  }   // Type check  const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']  if (!allowedTypes.includes(file.type)) {    throw new Error('Invalid file type')  }   // Extension check  const allowedExtensions = ['.jpg', '.jpeg', '.png', '.gif']  const extension = file.name.toLowerCase().match(/\.[^.]+$/)?.[0]  if (!extension || !allowedExtensions.includes(extension)) {    throw new Error('Invalid file extension')  }   return true}``` #### Verification Steps- [ ] All user inputs validated with schemas- [ ] File uploads restricted (size, type, extension)- [ ] No direct use of user input in queries- [ ] Whitelist validation (not blacklist)- [ ] Error messages don't leak sensitive info ### 3. SQL Injection Prevention #### FAIL: NEVER Concatenate SQL```typescript// DANGEROUS - SQL Injection vulnerabilityconst query = `SELECT * FROM users WHERE email = '${userEmail}'`await db.query(query)``` #### PASS: ALWAYS Use Parameterized Queries```typescript// Safe - parameterized queryconst { data } = await supabase  .from('users')  .select('*')  .eq('email', userEmail) // Or with raw SQLawait db.query(  'SELECT * FROM users WHERE email = $1',  [userEmail])``` #### Verification Steps- [ ] All database queries use parameterized queries- [ ] No string concatenation in SQL- [ ] ORM/query builder used correctly- [ ] Supabase queries properly sanitized ### 4. Authentication & Authorization #### JWT Token Handling```typescript// FAIL: WRONG: localStorage (vulnerable to XSS)localStorage.setItem('token', token) // PASS: CORRECT: httpOnly cookiesres.setHeader('Set-Cookie',  `token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`)``` #### Authorization Checks```typescriptexport async function deleteUser(userId: string, requesterId: string) {  // ALWAYS verify authorization first  const requester = await db.users.findUnique({    where: { id: requesterId }  })   if (requester.role !== 'admin') {    return NextResponse.json(      { error: 'Unauthorized' },      { status: 403 }    )  }   // Proceed with deletion  await db.users.delete({ where: { id: userId } })}``` #### Row Level Security (Supabase)```sql-- Enable RLS on all tablesALTER TABLE users ENABLE ROW LEVEL SECURITY; -- Users can only view their own dataCREATE POLICY "Users view own data"  ON users FOR SELECT  USING (auth.uid() = id); -- Users can only update their own dataCREATE POLICY "Users update own data"  ON users FOR UPDATE  USING (auth.uid() = id);``` #### Verification Steps- [ ] Tokens stored in httpOnly cookies (not localStorage)- [ ] Authorization checks before sensitive operations- [ ] Row Level Security enabled in Supabase- [ ] Role-based access control implemented- [ ] Session management secure ### 5. XSS Prevention #### Sanitize HTML```typescriptimport DOMPurify from 'isomorphic-dompurify' // ALWAYS sanitize user-provided HTMLfunction 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```typescript// next.config.jsconst 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:;      font-src 'self';      connect-src 'self' https://api.example.com;    `.replace(/\s{2,}/g, ' ').trim()  }]``` #### Verification Steps- [ ] User-provided HTML sanitized- [ ] CSP headers configured- [ ] No unvalidated dynamic content rendering- [ ] React's built-in XSS protection used ### 6. CSRF Protection #### CSRF Tokens```typescriptimport { 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```typescriptres.setHeader('Set-Cookie',  `session=${sessionId}; HttpOnly; Secure; SameSite=Strict`)``` #### Verification Steps- [ ] CSRF tokens on state-changing operations- [ ] SameSite=Strict on all cookies- [ ] Double-submit cookie pattern implemented ### 7. Rate Limiting #### API Rate Limiting```typescriptimport rateLimit from 'express-rate-limit' const limiter = rateLimit({  windowMs: 15 * 60 * 1000, // 15 minutes  max: 100, // 100 requests per window  message: 'Too many requests'}) // Apply to routesapp.use('/api/', limiter)``` #### Expensive Operations```typescript// Aggressive rate limiting for searchesconst searchLimiter = rateLimit({  windowMs: 60 * 1000, // 1 minute  max: 10, // 10 requests per minute  message: 'Too many search requests'}) app.use('/api/search', searchLimiter)``` #### Verification Steps- [ ] Rate limiting on all API endpoints- [ ] Stricter limits on expensive operations- [ ] IP-based rate limiting- [ ] User-based rate limiting (authenticated) ### 8. Sensitive Data Exposure #### Logging```typescript// FAIL: WRONG: Logging sensitive dataconsole.log('User login:', { email, password })console.log('Payment:', { cardNumber, cvv }) // PASS: CORRECT: Redact sensitive dataconsole.log('User login:', { email, userId })console.log('Payment:', { last4: card.last4, userId })``` #### Error Messages```typescript// FAIL: WRONG: Exposing internal detailscatch (error) {  return NextResponse.json(    { error: error.message, stack: error.stack },    { status: 500 }  )} // PASS: CORRECT: Generic error messagescatch (error) {  console.error('Internal error:', error)  return NextResponse.json(    { error: 'An error occurred. Please try again.' },    { status: 500 }  )}``` #### Verification Steps- [ ] No passwords, tokens, or secrets in logs- [ ] Error messages generic for users- [ ] Detailed errors only in server logs- [ ] No stack traces exposed to users ### 9. Blockchain Security (Solana) #### Wallet Verification```typescriptimport { verify } from '@solana/web3.js' async function verifyWalletOwnership(  publicKey: string,  signature: string,  message: string) {  try {    const isValid = verify(      Buffer.from(message),      Buffer.from(signature, 'base64'),      Buffer.from(publicKey, 'base64')    )    return isValid  } catch (error) {    return false  }}``` #### Transaction Verification```typescriptasync function verifyTransaction(transaction: Transaction) {  // Verify recipient  if (transaction.to !== expectedRecipient) {    throw new Error('Invalid recipient')  }   // Verify amount  if (transaction.amount > maxAmount) {    throw new Error('Amount exceeds limit')  }   // Verify user has sufficient balance  const balance = await getBalance(transaction.from)  if (balance < transaction.amount) {    throw new Error('Insufficient balance')  }   return true}``` #### Verification Steps- [ ] Wallet signatures verified- [ ] Transaction details validated- [ ] Balance checks before transactions- [ ] No blind transaction signing ### 10. Dependency Security #### Regular Updates```bash# Check for vulnerabilitiesnpm audit # Fix automatically fixable issuesnpm audit fix # Update dependenciesnpm update # Check for outdated packagesnpm outdated``` #### Lock Files```bash# ALWAYS commit lock filesgit add package-lock.json # Use in CI/CD for reproducible buildsnpm ci  # Instead of npm install``` #### Verification Steps- [ ] Dependencies up to date- [ ] No known vulnerabilities (npm audit clean)- [ ] Lock files committed- [ ] Dependabot enabled on GitHub- [ ] Regular security updates ## Security Testing ### Automated Security Tests```typescript// Test authenticationtest('requires authentication', async () => {  const response = await fetch('/api/protected')  expect(response.status).toBe(401)}) // Test authorizationtest('requires admin role', async () => {  const response = await fetch('/api/admin', {    headers: { Authorization: `Bearer ${userToken}` }  })  expect(response.status).toBe(403)}) // Test input validationtest('rejects invalid input', async () => {  const response = await fetch('/api/users', {    method: 'POST',    body: JSON.stringify({ email: 'not-an-email' })  })  expect(response.status).toBe(400)}) // Test rate limitingtest('enforces rate limits', async () => {  const requests = Array(101).fill(null).map(() =>    fetch('/api/endpoint')  )   const responses = await Promise.all(requests)  const tooManyRequests = responses.filter(r => r.status === 429)   expect(tooManyRequests.length).toBeGreaterThan(0)})``` ## Pre-Deployment Security Checklist Before ANY production deployment: - [ ] **Secrets**: No hardcoded secrets, all in env vars- [ ] **Input Validation**: All user inputs validated- [ ] **SQL Injection**: All queries parameterized- [ ] **XSS**: User content sanitized- [ ] **CSRF**: Protection enabled- [ ] **Authentication**: Proper token handling- [ ] **Authorization**: Role checks in place- [ ] **Rate Limiting**: Enabled on all endpoints- [ ] **HTTPS**: Enforced in production- [ ] **Security Headers**: CSP, X-Frame-Options configured- [ ] **Error Handling**: No sensitive data in errors- [ ] **Logging**: No sensitive data logged- [ ] **Dependencies**: Up to date, no vulnerabilities- [ ] **Row Level Security**: Enabled in Supabase- [ ] **CORS**: Properly configured- [ ] **File Uploads**: Validated (size, type)- [ ] **Wallet Signatures**: Verified (if blockchain) ## Resources - [OWASP Top 10](https://owasp.org/www-project-top-ten/)- [Next.js Security](https://nextjs.org/docs/security)- [Supabase Security](https://supabase.com/docs/guides/auth)- [Web Security Academy](https://portswigger.net/web-security) --- **Remember**: Security is not optional. One vulnerability can compromise the entire platform. When in doubt, err on the side of caution.