Claude Code Plugins

Community-maintained marketplace

Feedback

security-patterns

@romiluz13/cc10x
8
0

Identifies OWASP Top 10 vulnerabilities including SQL injection, XSS, authentication bypasses, insecure direct object references, CSRF, broken access control, and security misconfigurations. Use when analyzing code for security vulnerabilities, reviewing authentication and authorization logic, auditing input validation and output encoding, checking for injection attacks, or ensuring secure coding practices.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name security-patterns
description Identifies OWASP Top 10 vulnerabilities including SQL injection, XSS, authentication bypasses, insecure direct object references, CSRF, broken access control, and security misconfigurations. Use when analyzing code for security vulnerabilities, reviewing authentication and authorization logic, auditing input validation and output encoding, checking for injection attacks, or ensuring secure coding practices.

Security Patterns - Stage 1: Metadata

Skill Overview

Name: Security Patterns Purpose: Identify security vulnerabilities and ensure secure coding practices When to Use: Security analysis, code review, vulnerability scanning, auth implementation Core Rule: Assume all input is malicious until validated


Security Coverage

OWASP Top 10 Vulnerabilities:

  • A01: Broken Access Control (RBAC, ABAC)
  • A02: Cryptographic Failures (hashing, encryption, TLS)
  • A03: Injection (SQL, NoSQL, command, XSS)
  • A07: Authentication Failures (MFA, sessions, JWT)
  • Security headers
  • Rate limiting

Quick Facts

Aspect Details
OWASP Top 10 A01-A10 covered
Key Focus Input validation, auth, secrets
Common Mistakes Plain text passwords, no validation, hardcoded secrets
Red Flags eval, exec, innerHTML, hardcoded secrets
Best Practice Assume all input is malicious

When to Use

Always loaded at workflow start:

  • Shared context in REVIEW workflow
  • Shared context in BUILD workflow

Use when:

  • Implementing authentication
  • Handling payment processing
  • Storing sensitive data
  • Building public APIs
  • Analyzing code for vulnerabilities

Stage 2: Quick Reference

Authentication Decision Framework

Decision Matrix: JWT vs Sessions vs OAuth

Use JWT when:

  • Stateless microservices
  • Mobile apps (token refresh)
  • Cross-domain authentication
  • High read:write ratio

Use Sessions when:

  • Traditional web apps
  • Need instant revocation
  • Sensitive operations (banking)
  • Server-side rendering

Use OAuth when:

  • Third-party authentication
  • API delegation (Google, GitHub)
  • Multi-tenant SaaS
  • Social login

Critical JWT Pitfalls:

// INSECURE - No algorithm verification
const decoded = jwt.verify(token, secret);

// SECURE - Explicit algorithm
const decoded = jwt.verify(token, secret, { algorithms: ['HS256'] });

Injection Patterns

SQL Injection

// VULNERABLE
const query = `SELECT * FROM users WHERE email = '${email}'`;
db.query(query);
// Attack: email = "' OR '1'='1"

// SECURE - Parameterized queries
const query = 'SELECT * FROM users WHERE email = ?';
db.query(query, [email]);

NoSQL Injection (MongoDB)

// VULNERABLE
db.collection('users').findOne({ email: req.body.email });
// Attack: { "email": { "$ne": null } } returns all users

// SECURE - Type validation
const email = String(req.body.email);
if (typeof email !== 'string') throw new Error('Invalid input');
db.collection('users').findOne({ email });

XSS (Cross-Site Scripting)

// VULNERABLE
element.innerHTML = userInput;
// Attack: userInput = "<img src=x onerror='alert(1)'>"

// SECURE - Text nodes or sanitization
element.textContent = userInput;
// OR: use DOMPurify for HTML
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);

Command Injection

// VULNERABLE
exec(`convert ${filename} output.png`);
// Attack: filename = "image.jpg; rm -rf /"

// SECURE - Parameterized execution
execFile('convert', [filename, 'output.png']);

Access Control Patterns

Decision Framework: RBAC vs ABAC

Role-Based Access Control (RBAC):

// Use when: Fixed roles, simple permissions
const roles = {
  admin: ['read', 'write', 'delete'],
  editor: ['read', 'write'],
  viewer: ['read']
};

function hasPermission(user, action) {
  return roles[user.role]?.includes(action);
}

Attribute-Based Access Control (ABAC):

// Use when: Complex conditions, context-aware
function canEdit(user, document) {
  return user.id === document.ownerId
    || user.role === 'admin'
    || (user.department === document.department && user.role === 'manager');
}

Insecure Direct Object References (IDOR)

// VULNERABLE
app.get('/api/users/:id', (req, res) => {
  const user = db.users.findById(req.params.id);
  res.json(user); // Any user can access any ID
});

// SECURE - Authorization check
app.get('/api/users/:id', auth, (req, res) => {
  const requestedId = req.params.id;
  if (requestedId !== req.user.id && !req.user.isAdmin) {
    return res.status(403).json({ error: 'Forbidden' });
  }
  const user = db.users.findById(requestedId);
  res.json(user);
});

Cryptography Patterns

Password Hashing

// INSECURE
const hash = crypto.createHash('md5').update(password).digest('hex');

// SECURE - Bcrypt with salt
import bcrypt from 'bcrypt';
const saltRounds = 12;
const hash = await bcrypt.hash(password, saltRounds);
const isValid = await bcrypt.compare(inputPassword, hash);

Secrets Management

// INSECURE
const API_KEY = 'sk_live_abc123def456';

// SECURE - Environment variables
const API_KEY = process.env.STRIPE_API_KEY;
if (!API_KEY) throw new Error('Missing STRIPE_API_KEY');

// SECURE - Secret rotation
async function getSecret(name) {
  const secret = await secretsManager.getSecretValue(name);
  return JSON.parse(secret.SecretString);
}

Security Headers

// Express.js security headers
import helmet from 'helmet';

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
  }
}));

Rate Limiting

// Decision: When to rate limit
// - Public APIs: Always
// - Login endpoints: Always (prevent brute force)
// - Password reset: Always
// - File uploads: Always
// - Search: If expensive

import rateLimit from 'express-rate-limit';

const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 5, // 5 attempts
  message: 'Too many login attempts, try again later'
});

app.post('/api/login', loginLimiter, loginHandler);

Quick Security Checklist

Critical Checks (Before any code review):
- [ ] No hardcoded secrets (API keys, passwords)
- [ ] All inputs validated (type, length, format)
- [ ] SQL/NoSQL queries parameterized
- [ ] Passwords hashed with bcrypt/argon2
- [ ] Authentication on protected routes
- [ ] Authorization checks (IDOR prevention)
- [ ] CSRF protection on state-changing requests
- [ ] Security headers configured
- [ ] Rate limiting on public endpoints
- [ ] XSS prevention (escape output)
- [ ] HTTPS enforced
- [ ] Error messages don't leak sensitive info

Red Flags (Grep for these)

# Hardcoded secrets
grep -r "password.*=.*['\"]" --include="*.ts" --include="*.js"
grep -r "api[_-]?key.*=.*['\"]" --include="*.ts"

# Dangerous functions
grep -r "eval\|exec\|innerHTML\|dangerouslySetInnerHTML" src/

# SQL concatenation
grep -r "SELECT.*\${" --include="*.ts"

# Missing authentication
grep -r "app\.\(get\|post\|put\|delete\)" src/ | grep -v "auth\|Auth"