当前位置:

首页 > 编程开发 > Java项目如何防止SQL注入

Java项目如何防止SQL注入

SQLPro
SQLPro

SQLPro 是一款macOS平台上数据库管理应用,避免使用非法,享受更全面的支持和更新。它更贴近日常 macOS 使用场景,处理高频操作时整体会更顺手一些。

立即下载
¥119
macOS 2026-09-24
正版软件 macOS软件 数据库管理工具 macOS

一、什么是SQL注入SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。SQL案列Stringsql="deletefromtable1whereid="+"id";这个id从请求参数中获取,若参数被拼接为:1001or1=1最执行语句变为:Stringsql="deletefromtable1w

本文目录

      一、什么是SQL注入

      SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

      SQL案列

      String sql = "delete from table1 where id = " + "id";

      这个id从请求参数中获取,若参数被拼接为:

      1001 or  1 = 1

      最执行语句变为:

      String sql = "delete from table1 where id = 1001 or 1 = 1";

      此时,数据库的数据都会被清空掉,后果非常严重

      二、Java项目防止SQL注入方式

      这里总结4种:

      • PreparedStatement防止SQL注入

      • mybatis中#{}防止SQL注入

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

      • nginx反向代理防止SQL注入

      1、PreparedStatement防止SQL注入

      PreparedStatement具有预编译功能,以上述SQL为例

      使用PreparedStatement预编译后的SQL为:

      delete from table1 where id= ?

      此时SQL语句结构已固定,无论"?"被替换为任何参数,SQL语句只认为where后面只有一个条件,当再传入 1001 or  1 = 1时,语句会报错,从而达到防止SQL注入效果

      2、mybatis中#{}防止SQL注入

      mybatis中#{}表达式防止SQL注入与PreparedStatement类似,都是对SQL语句进行预编译处理

      注意:

      #{} :参数占位符

      ${} :拼接替换符,不能防止SQL注入,一般用于

      •  传入数据库对象(如:数据库名称、表名)

      •  order by  后的条件

      3、对请求参数的敏感词汇进行过滤

      这里是springboot的写法,如下:

      import org.springframework.context.annotation.Configuration;
      import javax.servlet.*;
      import javax.servlet.annotation.WebFilter;
      import java.io.IOException;
      import java.util.Enumeration;
       
      /**
       * @Auther: 睡竹
       * @Date: 2023/03/07
       * @Description: sql防注入过滤器
       */
      @WebFilter(urlPatterns = "/*",filterName = "sqlFilter")
      @Configuration
      public class SqlFilter implements Filter {
       
          @Override
          public void init(FilterConfig filterConfig) throws ServletException {}
       
          /**
           * @description sql注入过滤
           */
          @Override
          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
              ServletRequest request = servletRequest;
              ServletResponse response = servletResponse;
              // 获得所有请求参数名
              Enumeration names = request.getParameterNames();
              String sql = "";
              while (names.hasMoreElements()){
                  // 得到参数名
                  String name = names.nextElement().toString();
                  // 得到参数对应值
                  String[] values = request.getParameterValues(name);
                  for (int i = 0; i < values.length; i++) {
                      sql += values[i];
                  }
              }
              if (sqlValidate(sql)) {
                  //TODO 这里直接抛异常处理,前后端交互项目中,请把错误信息按前后端"数据返回的VO"对象进行封装
                  throw new IOException("您发送请求中的参数中含有非法字符");
              } else {
                  filterChain.doFilter(request,response);
              }
          }
       
          /**
           * @description 匹配效验
           */
          protected static boolean sqlValidate(String str){
              // 统一转为小写
              String s = str.toLowerCase();
              // 过滤掉的sql关键字,特殊字符前面需要加\\进行转义
              String badStr =
                      "select|update|and|or|delete|insert|truncate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute|table|"+
                              "char|declare|sitename|xp_cmdshell|like|from|grant|use|group_concat|column_name|" +
                              "information_schema.columns|table_schema|union|where|order|by|" +
                              "'\\*|\\;|\\-|\\--|\\+|\\,|\\//|\\/|\\%|\\#";
              //使用正则表达式进行匹配
              boolean matches = s.matches(badStr);
              return matches;
          }
       
          @Override
          public void destroy() {}
      }

      4、nginx反向代理防止SQL注入

      越来越多网站使用nginx进行反向代理,该层我们也可以进行防止SQL注入配置。

      将下面的Nginx配置文件代码放入到server块中,然后重启Nginx即可

       if ($request_method !~* GET|POST) { return 444; }
       #使用444错误代码可以更加减轻服务器负载压力。
       #防止SQL注入
       if ($query_string ~* (\$|'|--|[+|(%20)]union[+|(%20)]|[+|(%20)]insert[+|(%20)]|[+|(%20)]drop[+|(%20)]|[+|(%20)]truncate[+|(%20)]|[+|(%20)]update[+|(%20)]|[+|(%20)]from[+|(%20)]|[+|(%20)]grant[+|(%20)]|[+|(%20)]exec[+|(%20)]|[+|(%20)]where[+|(%20)]|[+|(%20)]select[+|(%20)]|[+|(%20)]and[+|(%20)]|[+|(%20)]or[+|(%20)]|[+|(%20)]count[+|(%20)]|[+|(%20)]exec[+|(%20)]|[+|(%20)]chr[+|(%20)]|[+|(%20)]mid[+|(%20)]|[+|(%20)]like[+|(%20)]|[+|(%20)]iframe[+|(%20)]|[\<|%3c]script[\>|%3e]|javascript|alert|webscan|dbappsecurity|style|confirm\(|innerhtml|innertext)(.*)$) { return 555; }
       if ($uri ~* (/~).*) { return 501; }
       if ($uri ~* (\\x.)) { return 501; }
       #防止SQL注入 
       if ($query_string ~* "[;'<>].*") { return 509; }
       if ($request_uri ~ " ") { return 509; }
       if ($request_uri ~ (\/\.+)) { return 509; }
       if ($request_uri ~ (\.+\/)) { return 509; }
       #if ($uri ~* (insert|select|delete|update|count|master|truncate|declare|exec|\*|\')(.*)$ ) { return 503; }
       #防止SQL注入
       if ($request_uri ~* "(cost\()|(concat\()") { return 504; }
       if ($request_uri ~* "[+|(%20)]union[+|(%20)]") { return 504; }
       if ($request_uri ~* "[+|(%20)]and[+|(%20)]") { return 504; }
       if ($request_uri ~* "[+|(%20)]select[+|(%20)]") { return 504; }
       if ($request_uri ~* "[+|(%20)]or[+|(%20)]") { return 504; }
       if ($request_uri ~* "[+|(%20)]delete[+|(%20)]") { return 504; }
       if ($request_uri ~* "[+|(%20)]update[+|(%20)]") { return 504; }
       if ($request_uri ~* "[+|(%20)]insert[+|(%20)]") { return 504; }
       if ($query_string ~ "(<|%3C).*script.*(>|%3E)") { return 505; }
       if ($query_string ~ "GLOBALS(=|\[|\%[0-9A-Z]{0,2})") { return 505; }
       if ($query_string ~ "_REQUEST(=|\[|\%[0-9A-Z]{0,2})") { return 505; }
       if ($query_string ~ "proc/self/environ") { return 505; }
       if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|\%3D)") { return 505; }
       if ($query_string ~ "base64_(en|de)code\(.*\)") { return 505; }
       if ($query_string ~ "[a-zA-Z0-9_]=http://") { return 506; }
       if ($query_string ~ "[a-zA-Z0-9_]=(\.\.//?)+") { return 506; }
       if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") { return 506; }
       if ($query_string ~ "b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)b") { return 507; }
       if ($query_string ~ "b(erections|hoodia|huronriveracres|impotence|levitra|libido)b") {return 507; }
       if ($query_string ~ "b(ambien|bluespill|cialis|cocaine|ejaculation|erectile)b") { return 507; }
       if ($query_string ~ "b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)b") { return 507; }
       #这里大家根据自己情况添加删减上述判断参数,cURL、wget这类的屏蔽有点儿极端了,但要“宁可错杀一千,不可放过一个”。
       if ($http_user_agent ~* YisouSpider|ApacheBench|WebBench|Jmeter|JoeDog|Havij|GetRight|TurnitinBot|GrabNet|masscan|mail2000|github|wget|curl|Java|python) { return 508; }
       #同上,大家根据自己站点实际情况来添加删减下面的屏蔽拦截参数。
       if ($http_user_agent ~* "Go-Ahead-Got-It") { return 508; }
       if ($http_user_agent ~* "GetWeb!") { return 508; }
       if ($http_user_agent ~* "Go!Zilla") { return 508; }
       if ($http_user_agent ~* "Download Demon") { return 508; }
       if ($http_user_agent ~* "Indy Library") { return 508; }
       if ($http_user_agent ~* "libwww-perl") { return 508; }
       if ($http_user_agent ~* "Nmap Scripting Engine") { return 508; }
       if ($http_user_agent ~* "~17ce.com") { return 508; }
       if ($http_user_agent ~* "WebBench*") { return 508; }
       if ($http_user_agent ~* "spider") { return 508; } #这个会影响国内某些搜索引擎爬虫,比如:搜狗
       #拦截各恶意请求的UA,可以通过分析站点日志文件或者waf日志作为参考配置。
       if ($http_referer ~* 17ce.com) { return 509; }
       #拦截17ce.com站点测速节点的请求,所以明月一直都说这些测速网站的数据仅供参考不能当真的。
       if ($http_referer ~* WebBench*") { return 509; }
       #拦截WebBench或者类似压力测试工具,其他工具只需要更换名称即可。
      本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
      作者最新文章
      编程开发 Java SQL
      相关文章 更多
      SQL主键约束和唯一约束有什么区别
      SQL主键约束和唯一约束有什么区别

      深入理解SQL PRIMARY KEY与UNIQUE约束的区别。文章从行标识与重复限制的目标出发,详解主键的非空特性、外键引用角色以及多数据库对NULL值的处理差异。结合users表实战示例,指导开发者如何根据字段稳定性与业务语义合理选择约束类型,避免设计误区。

      SQL约束有哪些类型及作用
      SQL约束有哪些类型及作用

      刚开始设计关系型数据库?了解PRIMARY KEY、FOREIGN KEY、UNIQUE、NOT NULL、CHECK、DEFAULT等约束的作用、语法和排错方法。本文以PostgreSQL语法为主,结合用户订单场景,清晰展示如何防止脏数据并处理常见约束冲突。

      SQL增删改操作规范:INSERT、UPDATE与DELETE语句详解
      SQL增删改操作规范:INSERT、UPDATE与DELETE语句详解

      掌握SQL增删改核心规范:INSERT必须指定列清单以防结构变更错误;UPDATE和DELETE执行前务必通过SELECT确认WHERE条件范围;利用事务BEGIN/ROLLBACK机制实现误操作回滚。本文结合PostgreSQL语法与跨库差异,提供从语句编写到结果验证的完整安全操作流程,帮助开发者规避生产环境数据风险。

      解决SQL插入数据违反约束的报错
      解决SQL插入数据违反约束的报错

      后端开发中遇到INSERT语句因约束失败报错怎么办?本文详解如何解读NOT NULL、UNIQUE、CHECK及FOREIGN KEY错误信息,通过查看表结构和对比输入参数快速定位原因,并提供修正数据、调整插入顺序及幂等处理的具体方案,帮助开发者高效解决数据库写入异常。

      用集合操作或临时表替代SQL游标的方法与案例
      用集合操作或临时表替代SQL游标的方法与案例

      开发者常因游标逐行处理导致SQL执行缓慢。本文详解如何使用集合操作(UPDATE FROM)、临时表批量JOIN以及按主键范围分批处理来替代游标。涵盖NULL值处理、索引优化及事务一致性检查,提供可落地的代码案例与验证方法。

      SQL游标常见错误排查:死锁与资源未释放问题
      SQL游标常见错误排查:死锁与资源未释放问题

      深入解析SQL游标导致的死锁与资源未释放问题。通过PostgreSQL与MySQL语法对比,展示如何识别长事务持锁、分析锁等待链,并提供短事务提交、异常清理及批量处理的最佳实践,确保数据库连接与锁资源及时释放。

      Java单元测试入门:使用JUnit 5编写第一个测试用例
      Java单元测试入门:使用JUnit 5编写第一个测试用例

      面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

      Java变量未初始化报错解析:局部变量与成员变量默认值差异
      Java变量未初始化报错解析:局部变量与成员变量默认值差异

      深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

      为什么SQL开发应尽量避免使用游标:性能瓶颈分析
      为什么SQL开发应尽量避免使用游标:性能瓶颈分析

      深入分析SQL游标在逐行FETCH时的性能瓶颈,包括往返开销、锁竞争及连接资源占用。提供将游标逻辑改写为集合操作(UPDATE/INSERT SELECT)的实战方法,以及必须逐行处理时的分批提交策略。通过EXPLAIN和锁监控验证优化效果,适用于评估数据库交互方案的后端开发者。

      Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
      Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

      详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

      查看更多
      精品专题 更多
      装机必备
      装机必备

      正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

      Windows
      Windows

      正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

      PDF教程
      PDF教程

      正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

      Mac软件 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      Aperty macOS版
      Aperty macOS版
      macOS

      Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

      WINDOWS 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      PixTV 网页版
      PixTV 网页版
      Windows

      PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。

      即将离开本站
      您即将前往第三方网站,请确认是否继续?