繁体   English   中英

避免SQL注入Spring JPA

[英]Avoid SQL Injection in Spring JPA

我正在使用sql query

String query = "Select  max(case when UPPER(key)='firstname' then value end) as firstNameName, , ...   order by "+orderBy;
result = em.createNativeQuery(query).getResultList();
em.close();

出于某种原因,我将不得不使用动态+orderBy 其中orderBy =firstname ASC, lastname DESC等。尝试使用.setParameter(1, orderedBy)但在这种情况下,我没有得到预期的排序结果。

为了避免 sql 注入威胁,您首先需要删除附加参数到您的查询。 当您在应用程序中附加参数时,攻击者可以劫持您的 sql 代码(例如使用撇号和其他方式)

例如:

如果您的查询是"select * from table where name="+id

攻击者可以传递给字段值,例如: 'John' or 1=1; -> 在此表中查看您的所有记录

甚至'John' or 1=1;Delete all from users;' -> 删除用户表中的所有条目。

劫持查询可以通过输入清理、输入白名单/黑名单(从输入中删除不需要的字符/定义允许或不允许的字符列表)等机制来避免。 大多数现代框架框架(如 JDBC/JPA/Hibernate)都可以提供针对这种威胁的保护。

综上所述,我们应该考虑以下情况:

考虑 sql 其中参数:

例如 JDBC 提供了准备好的语句,您在 sql 中定义了一个变量,框架将替换它

在您的情况下, JPA 实现(Hibernate)也具有避免这种威胁的机制,也通过参数化查询和位置参数:

  1. 通过本机查询位置参数:
Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = ?1");
q.setParameter(1, "test");

  1. 通过命名参数(jplq)
Query q = em.createQuery("SELECT count(*) FROM mytable where username = :username");
q.setParameter("username", "test");

考虑 orderBy 参数:

  1. CriteriaQuery /spring Specifications
 CriteriaBuilder cb = this.entityManager
                .getCriteriaBuilder();
    CriteriaQuery<RESULT> criteria = cb.createQuery(RESULT.class);
    Root<RESULT> root = criteria.from(RESULT.class);
    return this.entityManager.createQuery(
                 criteria.select(root).orderBy(cb.asc(root.get("ORDER_BY_FIELD"))))
           .getResultList();

有关 criteriaQueries 用法和配置的更多信息,请参见此处

  1. 通过预先构建的 spring 特定Sort参数传递orderBy (使用 spring-data 库)
Sort sort = Sort.by(Sort.Direction.ASC, "criteria");
em.createQuery(QueryUtils.applySorting(yourSqlQuery_withoutSorting,sort));

  1. 使用带有 spring-data 库的 @Query 注释方法:

您可以使用更少的样板代码(无需注入 entityManager 和创建 nativeQuery)实现相同的结果,只需使用@Query注释对方法进行注释:

 @Query("select u from User u where u.lastname like ?1%")
  List<User> findByAndSort(String lastname, Sort sort);

笔记:

本机与非本机 (jpql): JOQL 查询独立于数据库供应商(MySQL、PostGres、Oracle、DB2),当您需要使用不同供应商不同的数据库特定功能时,nativeQueries 的使用更加集中。 举个简单的例子jpql不能支持native [With] 2 clause PLSQL标准函数

关于您的编辑:

您可以尝试应用以下 sql 技巧进行动态排序:

SELECT param1, param2 ...
FROM ...
ORDER BY case when :sortParam='name asc' then name asc END
         case when :sortParam='name desc' then name desc END
         ....
         else 0


暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM