安全模式Skill security-patterns

此技能专注于实现全面的安全模式,保护应用程序免受OWASP Top 10漏洞如XSS、CSRF、SQL注入的侵害,关键词包括安全模式、OWASP、漏洞防护、应用程序安全、认证授权、数据加密、CSRF保护、XSS预防、API安全、速率限制、安全头配置,适用于开发安全关键应用,确保数据保护和系统安全。

安全审计 0 次安装 0 次浏览 更新于 3/18/2026

名称: 安全模式 描述: 实现全面的安全模式,以保护应用程序免受OWASP Top 10漏洞的侵害,包括XSS、CSRF、SQL注入、认证绕过和数据泄露。适用于处理用户数据、实现认证和授权、验证输入、加密敏感数据、防止注入攻击、保护API端点、管理会话和令牌、实施速率限制、配置安全头,或构建需要深度防御保护的安全关键功能。

安全模式 - 构建安全应用程序

何时使用此技能

  • 实现认证和授权系统
  • 处理敏感用户数据和个人信息
  • 验证和清理所有用户输入
  • 使用参数化查询防止SQL注入
  • 通过输出转义保护免受XSS攻击
  • 使用令牌实现CSRF保护
  • 加密静态和传输中的数据
  • 通过认证保护API端点
  • 配置安全头(CSP、HSTS等)
  • 实施速率限制和DDoS防护
  • 管理会话、JWT和认证令牌
  • 进行安全审计和漏洞评估

何时使用此技能

  • 处理用户数据、认证、授权或任何安全敏感操作时
  • 当处理相关任务或功能时
  • 在需要此专业知识的开发过程中

使用场景:处理用户数据、认证、授权或任何安全敏感操作时。

核心原则

  1. 深度防御 - 多层安全防护
  2. 最小权限原则 - 最小必要权限
  3. 安全失败 - 错误不应暴露敏感数据
  4. 永不信任用户输入 - 验证一切输入
  5. 安全设计 - 安全不是事后再考虑

OWASP Top 10 防护

1. 注入防护(SQL、NoSQL、命令)

// ❌ 易受攻击 - SQL注入
app.get('/user', (req, res) => {
  const query = `SELECT * FROM users WHERE id = '${req.query.id}'`;
  db.query(query); // 可以注入:?id=' OR '1'='1
});

// ✅ 安全 - 参数化查询
app.get('/user', (req, res) => {
  const query = 'SELECT * FROM users WHERE id = ?';
  db.query(query, [req.query.id]);
});

// ✅ 安全 - 带验证的ORM
app.get('/user', async (req, res) => {
  const userId = parseInt(req.query.id, 10);
  if (!userId || isNaN(userId)) {
    return res.status(400).json({ error: '无效ID' });
  }
  const user = await db.users.findById(userId);
  res.json(user);
});

2. 认证和会话管理

// ✅ 密码哈希(绝不存储明文)
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);
}

// ✅ JWT令牌认证
import jwt from 'jsonwebtoken';

function generateToken(userId) {
  return jwt.sign(
    { userId },
    process.env.JWT_SECRET, // 存储在环境变量中!
    { expiresIn: '1h' }
  );
}

function verifyToken(token) {
  try {
    return jwt.verify(token, process.env.JWT_SECRET);
  } catch (error) {
    return null;
  }
}

// ✅ 会话管理
import session from 'express-session';
import RedisStore from 'connect-redis';

app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: true, // 仅HTTPS
    httpOnly: true, // 无JavaScript访问
    maxAge: 1000 * 60 * 60 * 24, // 24小时
    sameSite: 'strict' // CSRF防护
  }
}));

3. XSS(跨站脚本)预防

// ❌ 易受攻击 - 直接HTML插入
app.get('/profile', (req, res) => {
  const html = `<h1>欢迎 ${req.query.name}</h1>`;
  res.send(html); // 可以注入:?name=<script>alert('xss')</script>
});

// ✅ 安全 - 模板转义(React自动转义)
function Profile({ name }) {
  return <h1>欢迎 {name}</h1>; // React默认转义
}

// ✅ 安全 - 富内容显式清理
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.setHeader(
    'Content-Security-Policy',
    "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
  );
  next();
});

4. CSRF(跨站请求伪造)防护

// ✅ CSRF令牌
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 });
});

// ✅ SameSite Cookies
res.cookie('session', sessionId, {
  sameSite: 'strict', // 防止CSRF
  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({ error: '无效来源' });
  }
  next();
});

5. 访问控制和授权

// ✅ 基于角色的访问控制(RBAC)
const ROLES = {
  ADMIN: 'admin',
  USER: 'user',
  GUEST: 'guest'
};

function requireRole(role) {
  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({ error: '未认证' });
    }
    
    if (req.user.role !== role) {
      return res.status(403).json({ error: '权限不足' });
    }
    
    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(userId, postId) {
  const post = await db.posts.findById(postId);
  if (!post) return false;
  
  // 用户可以编辑自己的帖子或如果是管理员
  const user = await db.users.findById(userId);
  return post.authorId === userId || user.role === 'admin';
}

app.put('/posts/:id', async (req, res) => {
  if (!await canEditPost(req.user.id, req.params.id)) {
    return res.status(403).json({ error: '无法编辑此帖子' });
  }
  
  const updated = await db.posts.update(req.params.id, req.body);
  res.json(updated);
});

6. 速率限制和DDoS防护

// ✅ 速率限制
import rateLimit from 'express-rate-limit';

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分钟
  max: 100, // 每个IP在窗口内限制为100个请求
  message: '请求过多,请稍后再试'
});

app.use('/api/', limiter);

// ✅ 认证端点的更严格限制
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5, // 每15分钟仅允许5次登录尝试
  skipSuccessfulRequests: true
});

app.post('/login', authLimiter, async (req, res) => {
  // 登录逻辑
});

// ✅ 基于Redis的速率限制(分布式)
import RedisStore from 'rate-limit-redis';

const limiter = rateLimit({
  store: new RedisStore({
    client: redisClient
  }),
  windowMs: 15 * 60 * 1000,
  max: 100
});

7. 敏感数据泄露预防

// ❌ 易受攻击 - 暴露敏感数据
app.get('/user/:id', async (req, res) => {
  const user = await db.users.findById(req.params.id);
  res.json(user); // 包括密码哈希、内部ID等!
});

// ✅ 安全 - 显式字段选择
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
    // 不包括passwordHash
  });
});

// ✅ 安全 - 使用DTO/序列化器
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 = await db.users.findById(req.params.id);
  res.json(UserDTO.fromUser(user));
});

// ✅ 加密静态敏感数据
import crypto from 'crypto';

function encrypt(text) {
  const key = Buffer.from(process.env.ENCRYPTION_KEY, 'hex');
  const iv = crypto.randomBytes(16);
  const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
  
  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  
  return iv.toString('hex') + ':' + encrypted;
}

function decrypt(encrypted) {
  const key = Buffer.from(process.env.ENCRYPTION_KEY, 'hex');
  const parts = encrypted.split(':');
  const iv = Buffer.from(parts[0], 'hex');
  const encryptedText = parts[1];
  const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
  
  let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  
  return decrypted;
}

8. 输入验证

// ✅ 使用Zod进行模式验证
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 'path';

const upload = multer({
  dest: 'uploads/',
  limits: {
    fileSize: 5 * 1024 * 1024 // 最大5MB
  },
  fileFilter: (req, file, cb) => {
    const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
    
    if (!allowedTypes.includes(file.mimetype)) {
      return cb(new Error('无效文件类型'));
    }
    
    cb(null, true);
  }
});

app.post('/upload', upload.single('avatar'), (req, res) => {
  res.json({ filename: req.file.filename });
});

9. 日志记录和监控

// ✅ 安全事件日志记录
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('登录尝试失败', {
      email: req.body.email,
      ip: req.ip,
      userAgent: req.get('user-agent'),
      timestamp: new Date().toISOString()
    });
    
    return res.status(401).json({ error: '无效凭证' });
  }
  
  res.json({ token: generateToken(user.id) });
});

// 记录权限提升尝试
app.put('/users/:id/role', requireAdmin, async (req, res) => {
  securityLogger.info('角色变更', {
    adminId: req.user.id,
    targetUserId: req.params.id,
    newRole: req.body.role,
    timestamp: new Date().toISOString()
  });
  
  await db.users.updateRole(req.params.id, req.body.role);
  res.json({ success: true });
});

10. 安全头

// ✅ 基本安全头
import helmet from 'helmet';

app.use(helmet()); // 自动设置多个头

// 或手动设置:
app.use((req, res, next) => {
  // 防止点击劫持
  res.setHeader('X-Frame-Options', 'DENY');
  
  // 防止MIME嗅探
  res.setHeader('X-Content-Type-Options', 'nosniff');
  
  // 启用XSS过滤器
  res.setHeader('X-XSS-Protection', '1; mode=block');
  
  // 严格传输安全(仅HTTPS)
  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();
});

环境和秘密管理

// ❌ 绝不要这样做
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(`缺少必需的环境变量: ${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.getSecretValue({ SecretId: secretName });
  return JSON.parse(response.SecretString);
}

安全检查清单

认证与会话:
□ 使用bcrypt/argon2哈希密码
□ JWT秘密安全存储
□ 实现令牌过期
□ 会话Cookie:httpOnly、secure、sameSite
□ 敏感操作的多因素认证可用

输入验证:
□ 使用模式验证所有输入
□ 防止SQL注入(参数化查询)
□ 防止XSS(输出转义)
□ 文件上传限制和验证
□ 重定向前验证URL

授权:
□ 保护路由需要认证
□ 实现基于角色的访问控制
□ 验证资源所有权
□ 强制执行最小权限原则

数据保护:
□ 强制使用HTTPS
□ 静态敏感数据加密
□ 秘密在环境变量中(不在代码中)
□ 日志/错误中无敏感数据
□ PII处理符合法规

基础设施:
□ 公共端点速率限制
□ 配置安全头
□ 正确配置CORS
□ 扫描依赖漏洞
□ 安全监控和告警

审计与合规:
□ 记录安全事件
□ 保留访问日志
□ 定期安全审计计划
□ 记录事件响应计划

资源


记住:安全不是可选的。必须从一开始就构建到每一层中。