🔐 今日秘术:JWT/OAuth2 攻防奥义
1. JWT 安全の六合阵法
// 🚫 危险操作:未验证签名
const decodeUnsafe = (token) => JSON.parse(atob(token.split('.')[1])); // ✅ 安全姿势一:严格签名验证
import jwt from 'jsonwebtoken';
const payload = jwt.verify(token, secretKey, { algorithms: ['HS256'] }); // ✅ 安全姿势二:强制过期时间检查
if (payload.exp < Date.now() / 1000) throw new Error('令牌已过期'); // ✅ 安全姿势三:关键声明校验
if (payload.iss !== 'my-auth-server') throw new Error('非法签发方'); // 🔥 防御算法切换攻击
// 服务端配置拒绝"none"算法
jwt.verify(token, secretKey, { algorithms: ['HS256', 'RS256'] });
🔔 攻击类型识别:
- 令牌泄露:通过XSS/网络嗅探获取JWT
- 签名绕过:篡改Header中的
alg:none
- 密钥爆破:弱密钥被暴力破解
2. OAuth2 防御の四象结界
// 🚫 危险配置:开放重定向漏洞
const redirectUri = req.query.redirect_uri; // 未经验证直接使用 // ✅ 安全姿势一:白名单验证
const validUris = ['https://app.com/callback'];
if (!validUris.includes(redirectUri)) return 403; // ✅ 安全姿势二:PKCE 增强
const codeVerifier = generateRandomString(64);
const codeChallenge = sha256(codeVerifier);
// 授权请求携带 challenge
redirectToAuthServer({ client_id, code_challenge: codeChallenge, code_challenge_method: 'S256'
}); // ✅ 安全姿势三:state参数防CSRF
const state = crypto.randomBytes(16).toString('hex');
storeInSession(state);
redirectToAuthServer({ state }); // 回调时校验state
if (req.query.state !== getFromSession()) throw new Error('非法请求');
❄️ 冷知识:现代安全机制
// 🛡️ Refresh Token 自动续期
let accessToken, refreshToken; async function refreshTokens() { try { const newTokens = await axios.post('/refresh', { refreshToken }); accessToken = newTokens.access; } catch (err) { // 刷新失败则要求重新登录 logout(); }
} // 🛡️ 浏览器安全存储
sessionStorage.setItem('token', token); // 标签页隔离
localStorage.setItem('refreshToken', encrypt(refreshToken)); // 加密存储 // 🛡️ 设备指纹绑定
const deviceId = generateFingerprint();
axios.post('/login', { ..., deviceId });
🌟 实验室安全工坊
实现安全令牌中间件
// JWT 安全校验中间件
const jwtAuth = (req, res, next) => { try { const token = req.headers.authorization?.split(' ')[1]; if (!token) return res.sendStatus(401); const payload = jwt.verify(token, publicKey, { algorithms: ['RS256'], issuer: 'auth-server', clockTolerance: 30 // 允许30秒时钟偏移 }); // 检查令牌是否被加入黑名单 if (redis.get(`jwt:${payload.jti}`)) return res.sendStatus(401); req.user = payload; next(); } catch (err) { res.status(401).json({ error: '令牌无效' }); }
}; // 令牌吊销端点
app.post('/logout', (req, res) => { const jti = req.user.jti; // JWT唯一标识 redis.set(`jwt:${jti}`, 'revoked', 'EX', 3600); // 吊销1小时 res.sendStatus(204);
});
明日秘境:《前端加密の奇门遁甲——HTTPS/数据加密实战》 🧪
(留言告诉我你遇到过的认证漏洞,本安全顾问为你定制防御结界!🔒)
🛎️ 本日避坑指南:
- JWT 十大危险操作
- 🚨 敏感数据存储于Payload
- 🚨 使用对称加密且密钥泄露
- 🚨 未设置合理的exp过期时间
- 🚨 接受任意签名算法
- 🚨 未处理令牌吊销场景
- OAuth2 安全红线
- 🚨 使用隐式授权(Implicit Flow)
- 🚨 允许任意redirect_uri
- 🚨 未校验response_type参数
- 🚨 客户端密钥明文存储
- 🚨 未使用PKCE增强移动端安全
- 安全头配置强化
# OAuth2 端点额外防护
add_header X-Content-Type-Options "nosniff" always;
add_header Cache-Control "no-store" always;
add_header Pragma "no-cache" always;
- 渗透测试工具
# JWT 攻击工具
https://github.com/ticarpi/jwt_tool # OAuth2 测试套件
https://github.com/oauth2-proxy/oauth2-proxy
🔮 安全工具速递
工具 | 用途 |
---|---|
jwt.io | JWT 在线调试工具 |
OpenSSL | 密钥对生成与管理 |
Postman | OAuth2 流程测试 |
Keycloak | 开源认证服务器 |
OWASP ZAP | 自动化安全扫描 |