业务开发重心大多放在功能实现、性能优化上,安全校验常常被简化甚至省略。很多安全漏洞不会立刻造成系统崩溃,但一旦被利用,会出现数据泄露、恶意篡改、账号被盗,甚至引发合规风险。
安全漏洞很多是开发习惯问题,并非高深攻击手段。本文盘点后端项目最容易踩的四大安全大坑,附带错误示例、原理讲解、生产可用防护代码,帮助团队建立基础安全编码规范。
一、后端四大高频安全漏洞
1. SQL注入
直接拼接用户输入参数到SQL语句,攻击者构造特殊字符,篡改SQL逻辑,查询、删除数据库内敏感数据。常见于字符串拼接SQL、MyBatis中使用${}直接取值。
2. XSS跨站脚本攻击
用户提交的文本内容不做过滤,直接展示在页面。攻击者植入JS脚本,其他用户访问页面时脚本执行,窃取Cookie、伪造用户操作,分为存储型XSS和反射型XSS。
3. CSRF跨站请求伪造
用户登录网站后,访问恶意页面,恶意页面自动发起请求,利用用户已登录身份执行操作,比如修改密码、提交订单、修改资料。
4. 权限越权(水平越权+垂直越权)
水平越权:A用户通过修改参数ID,查看/修改B用户数据;垂直越权:普通用户修改参数,访问管理员接口。这是业务系统出现最多的高危漏洞。
二、漏洞错误示例与防护代码
1. SQL注入防护
错误写法(直接拼接,存在注入)
// 禁止!字符串拼接SQL String sql = "select * from user where username = '" + username + "'";正确方案:使用预编译参数,MyBatis使用#{}占位符
<!-- 使用#{},参数预编译,防止注入 -->2. XSS防护
后端统一对用户输入进行转义过滤,过滤script、onclick等危险标签与事件;前端输出时开启转义。
// 简单工具方法,对输入内容做html转义 public static String htmlEscape(String content){ if(content == null) return null; content = content.replace("&","&"); content = content.replace("<","<"); content = content.replace(">",">"); content = content.replace("\"","""); content = content.replace("'","'"); return content; }3. CSRF防护
核心方案:接口请求携带Token,服务端校验Token。Token绑定用户会话,一次性或短时有效。
前端请求在header中携带 X-CSRF-Token,后端接口校验token合法性,GET查询接口一般不做CSRF校验,写接口(新增、修改、删除)强制校验。
4. 越权漏洞防护(业务最容易忽略)
错误逻辑:只根据前端传的orderId查询订单,不校验订单归属人
// 危险!仅根据id查询,可越权查看别人订单 Order order = orderMapper.selectById(orderId);正确逻辑:查询时带上当前登录用户ID,做数据归属校验
// 必须增加当前登录用户校验 Order order = orderMapper.selectByIdAndUserId(orderId, loginUserId); if(order == null){ throw new BusinessException("无权限访问该数据"); }核心原则:所有数据查询、修改,都要校验当前登录用户是否拥有该数据权限,不能信任前端传参
三、额外安全加固要点
接口入参校验:参数长度、格式、取值范围,拒绝非法超长输入
敏感信息脱敏:手机号、身份证、银行卡返回前端做脱敏处理
密码存储:禁止明文存储密码,使用BCrypt等不可逆加密算法
请求频率限流:防止暴力破解账号密码
错误页面不返回详细堆栈信息,避免泄露系统路径、数据库信息
四、安全落地检查清单
SQL语句是否全部使用预编译,杜绝字符串拼接SQL?
用户输入内容是否过滤,防止XSS脚本注入?
新增/修改/删除类接口是否开启CSRF Token校验?
所有数据操作接口,是否校验数据归属,防止越权访问?
密码是否加密存储,不保存明文?
敏感数据返回前端是否脱敏?
对外接口是否做参数校验、接口限流?
五、总结
Web安全防护,核心思路就是永远不要信任前端传来的任何参数。
绝大多数安全漏洞并非复杂攻击,而是开发编码习惯问题。在开发阶段就把注入、XSS、越权、CSRF纳入代码评审标准,上线前做安全扫描,能规避绝大多数安全事件,保护业务数据安全。