| name | security-patterns |
| description | Implement comprehensive security patterns to protect applications against OWASP Top 10 vulnerabilities including XSS, CSRF, SQL injection, authentication bypass, and data exposure. Use when handling user data, implementing authentication and authorization, validating input, encrypting sensitive data, preventing injection attacks, securing API endpoints, managing sessions and tokens, implementing rate limiting, configuring security headers, or building security-critical features that require defense-in-depth protection. |
Security Patterns - Building Secure Applications
When to use this skill
- Implementing authentication and authorization systems
- Handling sensitive user data and personal information
- Validating and sanitizing all user inputs
- Preventing SQL injection with parameterized queries
- Protecting against XSS attacks with output escaping
- Implementing CSRF protection with tokens
- Encrypting data at rest and in transit
- Securing API endpoints with authentication
- Configuring security headers (CSP, HSTS, etc.)
- Implementing rate limiting and DDoS protection
- Managing sessions, JWTs, and authentication tokens
- Conducting security audits and vulnerability assessments
When to use this skill
- Handling user data, authentication, authorization, or any security-sensitive operations.
- When working on related tasks or features
- During development that requires this expertise
Use when: Handling user data, authentication, authorization, or any security-sensitive operations.
Core Principles
- Defense in Depth - Multiple layers of security
- Principle of Least Privilege - Minimum necessary permissions
- Fail Securely - Errors shouldn't expose sensitive data
- Never Trust User Input - Validate everything
- Security by Design - Not an afterthought
OWASP Top 10 Protection
1. Injection Prevention (SQL, NoSQL, Command)
app.get('/user', (req, res) => {
const query = `SELECT * FROM users WHERE id = '${req.query.id}'`;
db.query(query);
});
app.get('/user', (req, res) => {
const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [req.query.id]);
});
app.get('/user', async (req, res) => {
const userId = parseInt(req.query.id, 10);
if (!userId || isNaN(userId)) {
return res.status(400).json({ error: 'Invalid ID' });
}
const user = await db.users.findById(userId);
res.json(user);
});
2. Authentication & Session Management
import bcrypt from 'bcrypt';
async function createUser(email, password) {
const SALT_ROUNDS = 10;
const passwordHash = await bcrypt.hash(password, SALT_ROUNDS);
return await db.users.create({
email,
passwordHash
});
}
async function verifyPassword(email, password) {
const user = await db.users.findOne({ email });
if (!user) return false;
return await bcrypt.compare(password, user.passwordHash);
}
import jwt from 'jsonwebtoken';
function generateToken(userId) {
return jwt.sign(
{ userId },
process.env.JWT_SECRET,
{ expiresIn: '1h' }
);
}
() {
{
jwt.(token, process..);
} (error) {
;
}
}
session ;
;
app.(({
: ({ : redisClient }),
: process..,
: ,
: ,
: {
: ,
: ,
: * * * ,
:
}
}));
3. XSS (Cross-Site Scripting) Prevention
app.get('/profile', (req, res) => {
const html = `<h1>Welcome ${req.query.name}</h1>`;
res.send(html);
});
function Profile({ name }) {
return <h1>Welcome {name}</h1>;
}
import DOMPurify from 'isomorphic-dompurify';
function RichContent({ html }) {
const sanitized = DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p'],
ALLOWED_ATTR: []
});
return <div dangerouslySetInnerHTML={{ __html: sanitized }} />;
}
app.use((req, res, next) => {
res.(
,
);
();
});
4. CSRF (Cross-Site Request Forgery) Protection
import csrf from 'csurf';
const csrfProtection = csrf({ cookie: true });
app.get('/form', csrfProtection, (req, res) => {
res.render('form', { csrfToken: req.csrfToken() });
});
app.post('/submit', csrfProtection, (req, res) => {
res.json({ success: true });
});
res.cookie('session', sessionId, {
sameSite: 'strict',
secure: true,
httpOnly: true
});
app.use((req, res, next) => {
const origin = req.get('origin') || req.get('referer');
if (origin && !origin.startsWith('https://yourdomain.com')) {
return res.status(403).json({ : });
}
();
});
5. Access Control & Authorization
const ROLES = {
ADMIN: 'admin',
USER: 'user',
GUEST: 'guest'
};
function requireRole(role) {
return (req, res, next) => {
if (!req.user) {
return res.status(401).json({ error: 'Not authenticated' });
}
if (req.user.role !== role) {
return res.status(403).json({ error: 'Insufficient permissions' });
}
next();
};
}
app.delete('/users/:id', requireRole(ROLES.ADMIN), async (req, res) => {
await db.users.delete(req.params.id);
res.json({ success: true });
});
async function canEditPost() {
post = db..(postId);
(!post) ;
user = db..(userId);
post. === userId || user. === ;
}
app.(, (req, res) => {
(! (req.., req..)) {
res.().({ : });
}
updated = db..(req.., req.);
res.(updated);
});
6. Rate Limiting & DDoS Protection
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
message: 'Too many requests, please try again later'
});
app.use('/api/', limiter);
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5,
skipSuccessfulRequests: true
});
app.post('/login', authLimiter, async (req, res) => {
});
import RedisStore from 'rate-limit-redis';
const limiter = rateLimit({
store: new RedisStore({
client: redisClient
}),
windowMs: 15 * 60 * 1000,
max:
});
7. Sensitive Data Exposure Prevention
app.get('/user/:id', async (req, res) => {
const user = await db.users.findById(req.params.id);
res.json(user);
});
app.get('/user/:id', async (req, res) => {
const user = await db.users.findById(req.params.id);
res.json({
id: user.id,
name: user.name,
email: user.email
});
});
class UserDTO {
static fromUser(user) {
return {
id: user.id,
name: user.name,
email: user.email,
createdAt: user.createdAt
};
}
}
app.get('/user/:id', async (req, res) => {
const user = db..(req..);
res.(.(user));
});
crypto ;
() {
key = .(process.., );
iv = crypto.();
cipher = crypto.(, key, iv);
encrypted = cipher.(text, , );
encrypted += cipher.();
iv.() + + encrypted;
}
() {
key = .(process.., );
parts = encrypted.();
iv = .(parts[], );
encryptedText = parts[];
decipher = crypto.(, key, iv);
decrypted = decipher.(encryptedText, , );
decrypted += decipher.();
decrypted;
}
8. Input Validation
import { z } from 'zod';
const CreateUserSchema = z.object({
email: z.string().email(),
password: z.string().min(8).max(100),
age: z.number().int().min(0).max(150),
website: z.string().url().optional()
});
app.post('/users', async (req, res) => {
try {
const validated = CreateUserSchema.parse(req.body);
const user = await createUser(validated);
res.json(user);
} catch (error) {
res.status(400).json({ error: error.errors });
}
});
import multer from 'multer';
import path from ;
upload = ({
: ,
: {
: * *
},
: {
allowedTypes = [, , ];
(!allowedTypes.(file.)) {
( ());
}
(, );
}
});
app.(, upload.(), {
res.({ : req.. });
});
9. Logging & Monitoring
import winston from 'winston';
const securityLogger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'security.log' })
]
});
app.post('/login', async (req, res) => {
const user = await verifyCredentials(req.body.email, req.body.password);
if (!user) {
securityLogger.warn('Failed login attempt', {
email: req.body.email,
ip: req.ip,
userAgent: req.get('user-agent'),
timestamp: new Date().toISOString()
});
return res.status(401).json({ error: 'Invalid credentials' });
}
res.json({ : (user.) });
});
app.(, requireAdmin, (req, res) => {
securityLogger.(, {
: req..,
: req..,
: req..,
: ().()
});
db..(req.., req..);
res.({ : });
});
10. Security Headers
import helmet from 'helmet';
app.use(helmet());
app.use((req, res, next) => {
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-XSS-Protection', '1; mode=block');
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
res.setHeader('Permissions-Policy', 'geolocation=(), microphone=(), camera=()');
next();
});
Environment & Secrets Management
const apiKey = 'sk_live_abc123';
const dbPassword = 'password123';
import dotenv from 'dotenv';
dotenv.config();
const apiKey = process.env.API_KEY;
const dbPassword = process.env.DB_PASSWORD;
const requiredEnvVars = [
'DATABASE_URL',
'JWT_SECRET',
'API_KEY'
];
for (const envVar of requiredEnvVars) {
if (!process.env[envVar]) {
console.error(`Missing required environment variable: ${envVar}`);
process.exit(1);
}
}
import { SecretsManager } from '@aws-sdk/client-secrets-manager';
async function getSecret(secretName) {
const client = new SecretsManager({ region: 'us-east-1' });
const response = await client.({ : secretName });
.(response.);
}
Security Checklist
Authentication & Sessions:
□ Passwords hashed with bcrypt/argon2
□ JWT secrets stored securely
□ Token expiration implemented
□ Session cookies: httpOnly, secure, sameSite
□ MFA available for sensitive operations
Input Validation:
□ All inputs validated with schema
□ SQL injection prevented (parameterized queries)
□ XSS prevented (output escaping)
□ File uploads restricted and validated
□ URLs validated before redirects
Authorization:
□ Authentication required for protected routes
□ Role-based access control implemented
□ Resource ownership verified
□ Principle of least privilege enforced
Data Protection:
□ HTTPS enforced everywhere
□ Sensitive data encrypted at rest
□ Secrets in environment variables (not code)
□ No sensitive data in logs/errors
□ PII handling compliant with regulations
Infrastructure:
□ Rate limiting on public endpoints
□ Security headers configured
□ CORS properly configured
□ Dependency vulnerabilities scanned
□ Security monitoring and alerting
Audit & Compliance:
□ Security events logged
□ Access logs retained
□ Regular security audits scheduled
□ Incident response plan documented
Resources
Remember: Security is not optional. It must be built into every layer from day one.