security-patterns
Security patterns for input validation, PII protection, and cryptographic operations
When & Why to Use This Skill
This Claude skill provides a comprehensive framework of security best practices and implementation patterns designed to safeguard applications. It focuses on critical defense mechanisms including robust input validation using Zod, automated PII (Personally Identifiable Information) protection, and secure cryptographic operations. By providing standardized templates for error handling and webhook verification, it helps developers prevent common vulnerabilities such as XSS, SQL injection, and data leaks, ensuring that AI-generated or human-written code adheres to high-standard security protocols.
Use Cases
- Case 1: Implementing strict server-side input validation using Zod schemas to prevent malicious data entry and ensure type safety across API endpoints.
- Case 2: Automating the sanitization of application logs to ensure sensitive user data like emails, tokens, and passwords are never exposed in monitoring tools.
- Case 3: Securing third-party integrations (e.g., Stripe webhooks) by implementing signature verification and replay attack protection to prevent unauthorized requests.
- Case 4: Establishing secure cryptographic standards for generating random tokens and encrypting sensitive data in client-side storage to mitigate session hijacking risks.
| name | security-patterns |
|---|---|
| description | Security patterns for input validation, PII protection, and cryptographic operations |
Security Patterns
Purpose: Security best practices (validation, PII protection, crypto, defense against vulnerabilities)
- Keywords: security, validation, auth, password, token, sanitize, xss, sql injection, zod, pii, webhook, signature, verify, encrypt, decrypt, hash, jwt, oauth, csrf, authentication, authorization, stripe
Quick Reference
| Category | ✅ DO | ❌ AVOID |
|---|---|---|
| Validation | Zod schemas with constraints | Trust client input |
| PII | sanitizeForLogging() |
Log emails, names, tokens |
| Crypto | crypto.randomInt() |
Math.random() |
| Storage | Encrypt localStorage | Store keys/passwords |
| Errors | Generic to client | Stack traces to client |
Input Validation (Zod)
import { z } from "zod"
const orderSchema = z.object({
name: z.string().min(1).max(100).trim(),
email: z.string().email().max(255).toLowerCase(),
amount: z.number().positive().max(1000000),
phone: z.string().regex(/^\+?[1-9]\d{1,14}$/).optional()
})
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E }
const validate = (input: unknown): Result<Order, z.ZodError> => {
const result = orderSchema.safeParse(input)
return result.success
? { ok: true, value: result.data }
: { ok: false, error: result.error }
}
Key: Use .safeParse(), add constraints (.min(), .max(), .trim()), return Result
PII Protection
import { sanitizeForLogging } from "./utils/sanitize"
// ✅ Auto-removes PII
logger.audit('order_created', sanitizeForLogging({
user_id: "123",
full_name: "John", // Removed
email: "john@example.com", // Removed
amount: 100
}))
// Logged: { user_id: "123", amount: 100 }
Auto-removed: Passwords, tokens, API keys, emails, names, SSN, cards, Bitcoin keys/addresses, phones
See resources/pii-protection.md for implementation.
Secure Random
import { randomInt } from "crypto"
// ✅ Cryptographically secure
const sessionId = randomInt(0, Number.MAX_SAFE_INTEGER).toString(36)
const code = randomInt(100000, 999999).toString()
// ✅ Browser
const array = new Uint32Array(1)
crypto.getRandomValues(array)
// ❌ NEVER for security
const code = Math.random() * 1000000
Secure Client Storage
import { encrypt, decrypt } from "./crypto"
const saveSession = (data: SessionData) => {
const encrypted = encrypt(JSON.stringify(data))
localStorage.setItem("session", encrypted)
}
// ❌ NEVER store Bitcoin keys/passwords (even encrypted)
Error Handling
export const createOrder = async (input: unknown) => {
try {
const order = await processOrder(input)
return { ok: true, value: order }
} catch (error) {
// ✅ Log full details server-side
logger.error('Order failed', {
error,
stack: error.stack,
input: sanitizeForLogging(input)
})
// ✅ Generic to client
return {
ok: false,
error: new Error("Failed to create order")
}
}
}
Webhook Verification
export const handleStripeWebhook = async (req: Request) => {
const signature = req.headers.get("stripe-signature")
const body = await req.text()
// ✅ Verify signature BEFORE processing
if (!verifySignature(body, signature, WEBHOOK_SECRET)) {
logger.warn('Invalid signature', { ip: req.headers.get("x-forwarded-for") })
return new Response("Invalid signature", { status: 401 })
}
// ✅ Check timestamp (replay attack)
const event = JSON.parse(body)
const eventTime = event.created * 1000
if (Date.now() - eventTime > 5 * 60 * 1000) {
return new Response("Timestamp too old", { status: 400 })
}
await processWebhookEvent(event)
return new Response("OK", { status: 200 })
}
Pre-Implementation Checklist
Before implementing, ask:
- ✅ Can users access data they shouldn't? (Authorization)
- ✅ Can this be automated/abused? (Rate limiting)
- ✅ Am I trusting client data? (Validation)
- ✅ Could this leak PII? (Sanitization)
- ✅ Can concurrent requests cause issues? (Race conditions)
- ✅ Can this be spammed? (Rate limiting, CAPTCHA)
If ANY "yes" → redesign before implementing
Rate Limits
| Action | Limit |
|---|---|
| Registration | 3/IP/24h |
| Login | 10/email/5min |
| Password reset | 3/email/hour |
| API calls | 100/user/hour |
See resources/rate-limiting.md
Incident Response
| Severity | Response | Examples |
|---|---|---|
| Critical | 4 hours | Breach, auth bypass |
| High | 24 hours | PII leak, privilege escalation |
| Medium | 3 days | XSS, CSRF |
Steps: Assess → Contain → Investigate → Patch → Notify (<72h if PII)
Resources
resources/input-validation.md- Zod patternsresources/pii-protection.md- Sanitizationresources/crypto-operations.md- Secure random, encryptionresources/rate-limiting.md- Rate limit implementation