🚀 快速安装
复制以下命令并运行,立即安装此 Skill:
npx @anthropic-ai/skills install supercent-io/skills-template/security-best-practices
💡 提示:需要 Node.js 和 NPM
安全最佳实践
何时使用此技能
- 新项目:从一开始就考虑安全性
- 安全审计:检查和修复漏洞
- 公共 API:强化可对外访问的 API
- 合规性:遵守 GDPR、PCI-DSS 等法规
指示
步骤 1:强制使用 HTTPS 和安全头部
Express.js 安全中间件:
import express from 'express';
import helmet from 'helmet';
import rateLimit from 'express-rate-limit';
const app = express();
// Helmet:自动设置安全头部
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", "https://trusted-cdn.com"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
connectSrc: ["'self'", "https://api.example.com"],
fontSrc: ["'self'", "https:", "data:"],
objectSrc: ["'none'"],
mediaSrc: ["'self'"],
frameSrc: ["'none'"],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
}
}));
// 强制使用 HTTPS
app.use((req, res, next) => {
if (process.env.NODE_ENV === 'production' && !req.secure) {
return res.redirect(301, `https://${req.headers.host}${req.url}`);
}
next();
});
// 速率限制(DDoS 防护)
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 分钟
max: 100, // 每个 IP 最多 100 次请求
message: '来自此 IP 的请求过多,请稍后再试。',
standardHeaders: true,
legacyHeaders: false,
});
app.use('/api/', limiter);
// 对认证端点实施更严格的限制
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5, // 每 15 分钟仅 5 次
skipSuccessfulRequests: true // 不计数成功请求
});
app.use('/api/auth/login', authLimiter);
步骤 2:输入验证(防止 SQL 注入、XSS)
Joi 验证:
import Joi from 'joi';
const userSchema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(8).pattern(/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/).required(),
name: Joi.string().min(2).max(50).required()
});
app.post('/api/users', async (req, res) => {
// 1. 验证输入
const { error, value } = userSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details[0].message });
}
// 2. 防止 SQL 注入:参数化查询
// ❌ 反面示例
// db.query(`SELECT * FROM users WHERE email = '${email}'`);
// ✅ 正确示例
const user = await db.query('SELECT * FROM users WHERE email = ?', [value.email]);
// 3. 防止 XSS:输出编码
// React/Vue 会自动转义;否则请使用库
import DOMPurify from 'isomorphic-dompurify';
const sanitized = DOMPurify.sanitize(userInput);
res.json({ user: sanitized });
});
步骤 3:防止 CSRF
CSRF 令牌:
import csrf from 'csurf';
import cookieParser from 'cookie-parser';
app.use(cookieParser());
// CSRF 防护
const csrfProtection = csrf({ cookie: true });
// 提供 CSRF 令牌
app.get('/api/csrf-token', csrfProtection, (req, res) => {
res.json({ csrfToken: req.csrfToken() });
});
// 在所有 POST/PUT/DELETE 请求上验证 CSRF
app.post('/api/*', csrfProtection, (req, res, next) => {
next();
});
// 在客户端使用
// fetch('/api/users', {
// method: 'POST',
// headers: {
// 'CSRF-Token': csrfToken
// },
// body: JSON.stringify(data)
// });
步骤 4:管理密钥
.env(切勿提交):
# 数据库
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
# JWT
ACCESS_TOKEN_SECRET=your-super-secret-access-token-key-min-32-chars
REFRESH_TOKEN_SECRET=your-super-secret-refresh-token-key-min-32-chars
# API 密钥
STRIPE_SECRET_KEY=sk_test_xxx
SENDGRID_API_KEY=SG.xxx
Kubernetes 密钥:
apiVersion: v1
kind: Secret
metadata:
name: myapp-secrets
type: Opaque
stringData:
database-url: postgresql://user:password@postgres:5432/mydb
jwt-secret: your-jwt-secret
// 从环境变量读取
const dbUrl = process.env.DATABASE_URL;
if (!dbUrl) {
throw new Error('需要设置 DATABASE_URL 环境变量');
}
步骤 5:安全的 API 认证
JWT + 刷新令牌轮换:
// 短生命周期访问令牌(15 分钟)
const accessToken = jwt.sign({ userId }, ACCESS_SECRET, { expiresIn: '15m' });
// 长生命周期刷新令牌(7 天),存储在数据库中
const refreshToken = jwt.sign({ userId }, REFRESH_SECRET, { expiresIn: '7d' });
await db.refreshToken.create({
userId,
token: refreshToken,
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
});
// 刷新令牌轮换:每次使用时重新发放
app.post('/api/auth/refresh', async (req, res) => {
const { refreshToken } = req.body;
const payload = jwt.verify(refreshToken, REFRESH_SECRET);
// 使现有令牌失效
await db.refreshToken.delete({ where: { token: refreshToken } });
// 发放新令牌
const newAccessToken = jwt.sign({ userId: payload.userId }, ACCESS_SECRET, { expiresIn: '15m' });
const newRefreshToken = jwt.sign({ userId: payload.userId }, REFRESH_SECRET, { expiresIn: '7d' });
await db.refreshToken.create({
userId: payload.userId,
token: newRefreshToken,
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
});
res.json({ accessToken: newAccessToken, refreshToken: newRefreshToken });
});
约束条件
必需规则(必须遵守)
- 仅 HTTPS:生产环境必须使用 HTTPS
- 密钥分离:通过环境变量管理;切勿硬编码在代码中
- 输入验证:验证所有用户输入
- 参数化查询:防止 SQL 注入
- 速率限制:防止 DDoS 攻击
禁止事项(不得违反)
- 不使用 eval():存在代码注入风险
- 不直接使用 innerHTML:存在 XSS 风险
- 不提交密钥:切勿提交 .env 文件
OWASP Top 10 检查清单
- [ ] A01:访问控制失效 - 基于角色的访问控制、授权检查
- [ ] A02:加密失败 - HTTPS、加密
- [ ] A03:注入 - 参数化查询、输入验证
- [ ] A04:不安全设计 - 安全设计原则
- [ ] A05:安全配置错误 - Helmet、更改默认密码
- [ ] A06:易受攻击的组件 - npm audit、定期更新
- [ ] A07:认证失败 - 强认证、多因素认证
- [ ] A08:数据完整性失败 - 签名验证、CSRF 防护
- [ ] A09:日志记录失败 - 安全事件日志记录
- [ ] A10:服务端请求伪造 - 验证出站请求
最佳实践
- 最小权限原则:授予最小必要权限
- 纵深防御:多层安全防护
- 安全审计:定期进行安全审查
参考资料
元数据
版本
- 当前版本:1.0.0
- 最后更新:2025-01-01
- 兼容平台:Claude, ChatGPT, Gemini
相关技能
标签
#安全 #OWASP #HTTPS #CORS #XSS #SQL注入 #CSRF #基础设施
示例
示例 1:基本用法
示例 2:高级用法
📄 原始文档
完整文档(英文):
https://skills.sh/supercent-io/skills-template/security-best-practices
💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

评论(0)