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

Java项目防止SQL注入的四种方案!
最新回答
晚安旧恋人

2026-06-09 04:01:01

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

SQL注入是一种常见的安全威胁,攻击者通过在输入中插入恶意SQL代码来操纵数据库查询。以下是Java项目中防止SQL注入的四种有效方案:

  • 使用PreparedStatement防止SQL注入

PreparedStatement是Java JDBC提供的一种预编译SQL语句机制。通过使用参数化查询,PreparedStatement可以有效地防止SQL注入。

示例代码:

String sql = "DELETE FROM table1 WHERE id = ?";PreparedStatement pstmt = connection.prepareStatement(sql);pstmt.setInt(1, id); // 设置参数值pstmt.executeUpdate();

原理:PreparedStatement在执行前会将SQL语句进行预编译,参数值会被视为纯文本而非SQL代码,从而避免了SQL注入的风险。

  • MyBatis中使用#{}防止SQL注入

MyBatis是一个流行的Java持久层框架,它支持参数化查询,通过使用#{}占位符来防止SQL注入。

示例代码:

<delete id="deleteById" parameterType="int"> DELETE FROM table1 WHERE id = #{id}</delete>

原理:MyBatis在处理#{}占位符时,会将其替换为?,并使用PreparedStatement进行预编译,从而防止SQL注入。

注意:MyBatis中的${}是字符串替换符,不能防止SQL注入,一般用于动态表名或列名。

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

在Spring Boot项目中,可以通过实现过滤器(Filter)来对请求参数进行敏感词汇过滤,防止SQL注入。

示例代码:

@WebFilter(urlPatterns = "/*", filterName = "sqlFilter")@Configurationpublic class SqlFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Enumeration<String> parameterNames = request.getParameterNames(); while (parameterNames.hasMoreElements()) { String paramName = parameterNames.nextElement(); String[] paramValues = request.getParameterValues(paramName); for (String paramValue : paramValues) { if (sqlValidate(paramValue)) { throw new ServletException("非法参数"); } } } chain.doFilter(request, response); } private boolean sqlValidate(String str) { String badStr = "select|update|delete|insert|truncate|char|into|substr|ascii|declare|exec|count|master|drop|execute|table"; return str.toLowerCase().matches(".*(" + badStr + ").*"); }}

原理:通过正则表达式匹配请求参数中的敏感词汇,如select、update等,如果发现匹配则拒绝请求。

  • Nginx反向代理防止SQL注入

Nginx可以作为反向代理服务器,通过配置规则来拦截和过滤恶意请求,防止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 444;}

原理:Nginx通过正则表达式匹配请求中的恶意字符串,如SQL关键字和特殊字符,如果匹配则返回错误代码或拒绝请求。

总结:以上四种方案各有优缺点,可以结合使用以提高安全性:

  1. PreparedStatement和MyBatis的#{}是代码层面的防护,直接有效。
  2. 请求参数过滤可以在应用层面进行二次防护。
  3. Nginx反向代理可以在网络层面进行防护,减轻应用服务器压力。

通过多层次的防护,可以大大降低SQL注入的风险。