Java项目防止SQL注入的四种方案!

🔔1. 什么是SQL注入?

SQL注入(SQL Injection)是一种代码注入技术,是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。简单来说,SQL注入攻击者通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,传入后端的SQL服务器执行。结果是可以执行恶意攻击者设计的任意SQL命令。例如,Web应用程序具有以下登录页面:

yaml 复制代码
User Name: admin
Password: 1234

攻击者在密码框中输入:

arduino 复制代码
'1234 ' or '1'='1

之后构造的SQL查询为:

ini 复制代码
SELECT * FROM users WHERE name='admin' AND password='1234 ' or '1'='1';

由于'或'1'='1 总是为真,所以可以绕过密码验证登录系统。SQL注入可以通过多种方式进行防范,如使用参数化的SQL语句、输入验证和过滤等方法。

在设计应用时必须注意对用户输入进行过滤,避免SQL注入漏洞。

🔔2. 防止SQL注入方式

🌵2.1 PreparedStatement防止SQL注入

使用PreparedStatement可以有效防止SQL注入攻击。PreparedStatement会先将SQL语句发送到数据库进行预编译,之后再将参数值单独传递,从而避免了SQL语句拼接的过程。例如,使用Statement时:

ini 复制代码
String sql = "SELECT * FROM users WHERE name = '" + username +"'" + " AND password = '" + password + "'";

这里存在SQL注入风险。使用PreparedStatement:

ini 复制代码
String sql = "SELECT * FROM users WHERE name = ? AND password = ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, username); 
stmt.setString(2, password);

PreparedStatement会区分SQL语句字符串和参数值,用?作为占位符,之后调用setString()等方法设置参数,这样可以有效防止SQL注入。

🌵2.2 mybatis中#{}防止SQL注入

在MyBatis中,可以使用#{}来防止SQL注入。#{}是MyBatis提供的PreparedStatement的参数占位符。MyBatis会自动将#{}替换为? ,并且对用户传入的参数自动进行Escape处理,以防止SQL注入。例如:

csharp 复制代码
<select id="findUser" parameterType="String" resultType="User">
  select * from user where name = #{name}
</select>

在Mapper接口中:

arduino 复制代码
User findUser(String name);

在这里,传入的name参数会被直接传递给PreparedStatement作为参数,而不是拼接到SQL语句中,所以安全。如果使用${}进行拼接:

sql 复制代码
select * from user where name = '${name}' 

那么就存在SQL注入风险。所以在MyBatis中,应该始终使用#{}进行参数传递,而不是${}字符串拼接,以防止SQL注入攻击。

🌵2.3 对请求参数的敏感词汇进行过滤

对用户请求参数中的敏感词汇进行过滤,可以防止多种注入攻击,包括SQL注入、XSS等。 常见的防范措施包括:

  1. 构建敏感词汇库,收集所有可能的敏感词汇,如delete、drop、script等。并定期更新。
  2. 对用户请求参数进行遍历,判断参数值是否包含敏感词汇。 可以用正则表达式或包含关系来判断。
  3. 一旦发现参数值存在敏感词汇,可以采取以下措施:
  • 返回错误,拒绝请求
  • 删除敏感词汇后,再进行后续处理
  • 将敏感词汇替换为安全的占位符,如replace('delete', '***')
  1. 对关键参数与业务规则进行校验,例如长度、类型、允许范围等。
  2. 考虑在边界处过滤,如WAF、防火墙等。
  3. 避免直接在SQL中拼接参数,应使用参数化查询
  4. 输出时对敏感数据编码或替换。

🌵2.4 nginx反向代理防止SQL注入

nginx作为反向代理服务器,可以实现一些防范SQL注入的措施:

  1. 请求参数过滤 可以使用nginx的ngx_http_rewrite_module模块,在server区域加入过滤规则,对请求参数中敏感字符进行过滤或拦截,例如:
bash 复制代码
if ($args ~* "select|insert|update|delete|drop|exec") {
 return 403;
}
  1. WAF功能 启用nginx的Web应用防火墙功能,对疑似SQL注入的请求进行拦截,如检测特殊字符,语句规则等。
  2. 访问控制 通过nginx的access模块,禁止某些IP地址或子网段访问,限制请求频率,以防止滥用。
  3. 隐藏数据库结构信息 nginx可以基于请求中的User-Agent等信息,显示不同的错误页面,避免泄露数据库元信息。
  4. 连接数据库的用户权限控制 只允许访问应用需要的最小权限集。

🔔写在最后

如果大家对相关文章感兴趣,可以关注公众号"架构殿堂",会持续更新AIGC,java基础面试题, netty, spring boot, spring cloud等系列文章,一系列干货随时送达!

相关推荐
绝无仅有32 分钟前
大厂Redis高级面试题与答案
后端·面试·github
Java进阶笔记32 分钟前
JVM默认栈大小
java·jvm·后端
绝无仅有35 分钟前
面试问题之导致 SQL 查询慢的原因及优化建议
后端·面试·github
在线教学养猪1 小时前
Spring Task
java·后端·spring
bobz9651 小时前
bpftune
后端
IT_陈寒1 小时前
React 性能优化必杀技:这5个Hook组合让你的应用提速50%!
前端·人工智能·后端
FenceRain1 小时前
spring boot 拦截器增加语言信息
java·spring boot·后端
weixin_436525072 小时前
Spring Boot 集成 EasyExcel 的最佳实践:优雅实现 Excel 导入导出
java·spring boot·后端
ChinaRainbowSea2 小时前
9. LangChain4j + 整合 Spring Boot
java·人工智能·spring boot·后端·spring·langchain·ai编程
shengjk12 小时前
一文搞懂 Flink2.x 分离式状态管理
后端