首页
Search
1
解决 docker run 报错 oci runtime error
49,608 阅读
2
WebStorm2025最新激活码
28,204 阅读
3
互点群、互助群、微信互助群
23,060 阅读
4
常用正则表达式
21,664 阅读
5
罗技鼠标logic g102驱动程序lghub_installer百度云下载windows LIGHTSYNC
20,037 阅读
自习室
互通有无
搞钱日记
养生记
包罗万象
Search
标签搜索
职场副业
职业发展
副业赚钱
后端开发
内容创作
微服务
分布式系统
效率提升
DevOps
技能提升
流量变现
性能优化
云原生
高并发
编程学习
深度学习
人工智能
架构设计
机器学习
前端开发
loong
累计撰写
3,206
篇文章
累计收到
4
条评论
首页
栏目
自习室
互通有无
搞钱日记
养生记
包罗万象
页面
搜索到
1
篇与
的结果
2026-01-15
Java后端安全实战:用代码说话,拆解OWASP Top 10核心防御策略
Java后端安全实战:用代码说话,拆解OWASP Top 10核心防御策略上周和一位做渗透测试的朋友吃饭,他半开玩笑地说:“你们Java开发写的接口,有时候就像没锁的门,我都不好意思进去。” 这话听着刺耳,但仔细一想,很多安全问题确实源于开发时“默认安全”的错觉。OWASP Top 10是个很好的安全风险清单,但光知道风险名称没用。关键在于,我们如何在日常的Java代码里,把这些抽象的威胁变成具体的防御逻辑。从“注入”到“免疫”:参数化查询不是万能药提到注入,大家第一反应是SQL注入,然后搬出PreparedStatement。这没错,但故事没完。// 这是基础操作,但很多人只做到这一步 String sql = "SELECT * FROM users WHERE id = ?"; PreparedStatement stmt = connection.prepareStatement(sql); stmt.setString(1, userId);真正的问题是,你的ORM框架用对了吗?MyBatis里用${}和#{}是天壤之别。更隐蔽的是,HQL或JPQL里的注入风险,容易被忽略。<!-- 危险!直接拼接 --> <select id="findUser" resultType="User"> SELECT * FROM users WHERE name = '${name}' </select> <!-- 安全!参数化 --> <select id="findUser" resultType="User"> SELECT * FROM users WHERE name = #{name} </select>还有一点,NoSQL数据库(比如MongoDB)的注入是另一回事,不能靠参数化查询解决,需要严格的输入验证和序列化处理。失效的身份认证:别只盯着密码强度认证逻辑的漏洞,往往藏在细节里。会话管理:你用Java EE的HttpSession,还是Spring Security的SecurityContext?默认的会话超时设置是30分钟,这个时间对后台管理系统可能太长,对网银应用可能又太短。关键操作(如修改密码、转账)是否需要重新认证?// Spring Security中强制会话失效的示例 @PostMapping("/change-password") public String changePassword(..., HttpServletRequest request) { // ... 密码修改逻辑 // 关键操作后,使当前会话失效,强制重新登录 SecurityContextHolder.clearContext(); HttpSession session = request.getSession(false); if (session != null) { session.invalidate(); } return "redirect:/login?changed"; }密码存储:别再提MD5了。用BCrypt、SCrypt或Argon2。Spring Security的PasswordEncoder已经帮我们封装好了,直接用。@Bean public PasswordEncoder passwordEncoder() { // 推荐使用BCrypt,强度(strength)通常设为10-12 return new BCryptPasswordEncoder(12); }但更重要的是,要有完善的账户锁定机制和可疑活动监控。连续5次登录失败就锁定账户15分钟,这个逻辑你实现了吗?敏感数据泄露:日志、响应和中间件开发时为了方便调试,我们常把敏感数据打印到日志。// 灾难性的日志记录 log.info("用户{}登录成功,token:{}", username, jwtToken); log.info("收到支付请求,卡号:{}, 金额:{}", cardNumber, amount);上线前,必须用代码扫描工具(如SonarQube)或自定义规则检查所有日志语句。对于身份证号、手机号、银行卡号,显示时至少要做部分掩码。public static String maskSensitiveInfo(String input) { if (input == null || input.length() < 4) { return input; } // 例如手机号:138****1234 return input.substring(0, 3) + "****" + input.substring(input.length() - 4); }API响应里的敏感字段,用@JsonIgnore注解过滤掉,别让整个用户对象直接返回给前端。public class UserDTO { private String username; private String email; @JsonIgnore // 关键!防止密码哈希值泄露 private String passwordHash; // ... getters and setters }XML外部实体(XXE):被遗忘的漏洞现在很多API都用JSON了,但处理上传的XML文件、集成老旧系统或使用SOAP时,XXE风险依然存在。默认的Java XML解析器(如DocumentBuilderFactory)是不安全的。// 错误配置:危险! DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(inputStream); // 正确配置:禁用外部实体 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 关键的三行配置 factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); factory.setFeature("http://xml.org/sax/features/external-general-entities", false); factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); DocumentBuilder builder = factory.newDocumentBuilder();如果使用第三方库,比如Jackson处理XML,也要确保其配置为安全模式。安全依赖管理:你的pom.xml安全吗?这是最容易自动化,也最容易被忽视的一点。你引入的fastjson 1.2.24可能有反序列化漏洞,log4j 2.14.0更是人尽皆知。光靠人工记不住。必须把它变成流程:用工具扫描:在CI/CD流水线中加入OWASP Dependency-Check或Snyk。定期升级:不是所有警告都要立刻处理,但要建立清单,有计划地升级高危依赖。使用可信源:确保公司内部Maven仓库代理了中央仓,并过滤掉已知的恶意组件。配置错误:从生产环境的第一道防线说起“配置错误”听起来像是运维的事,但开发脱不了干系。你是否提供了安全的默认配置? Spring Boot的application.properties里,management.endpoints.web.exposure.include=* 在开发环境方便,但绝不能出现在生产环境的配置模板中。错误信息是否过于友好? 栈轨迹直接返回给用户,等于给攻击者画地图。Spring Boot中,通过server.error.include-stacktrace=never来控制。不必要的服务是否开启? 比如Swagger UI、Actuator端点,生产环境必须通过权限控制或直接关闭。把安全变成习惯,而不是负担说实话,安全措施有时会影响开发效率,比如严格的输入验证、复杂的密码策略。但安全漏洞的代价更高。我的建议是:左移:在需求评审和设计阶段就考虑安全,而不是等到测试甚至上线后。工具化:把静态代码扫描(SAST)、依赖检查、动态扫描(DAST)集成到你的CI/CD流水线,让机器去做重复的检查。代码即文档:你写的安全处理代码,本身就是最好的安全规范。把常用的安全工具类(如输入验证、输出编码、密码工具)封装好,让团队所有人方便地用起来。安全不是某个人的职责,而是整个研发团队的文化。下次写代码时,不妨多问自己一句:“如果这个接口被恶意调用,会发生什么?” 这个简单的习惯,能挡住大部分低级却危险的问题。你团队里最容易被忽略的安全盲点,又是什么呢?
2026年01月15日
23 阅读
0 评论
0 点赞