Prevent JPQL query sql injection

限于喜欢 提交于 2019-12-11 06:57:09

问题


I was advised that below query is not safe as parameter :searchFor coming from input field in front end can be used for SQL injection. Plase advise what is the best solution to prevent SQL injection in below code?

@Query("SELECT u FROM User u WHERE lower(u.username) LIKE %:searchFor% " +
        " OR lower(concat(u.firstname, ' ', u.lastname)) LIKE %:searchFor% " +
        " OR lower(u.email) LIKE %:searchFor%")
Page<User> findAllAndSearch(@Param(value = "searchFor") String searchFor, Pageable pageable);

I am not using "+" to join strings, but provide parameter instead (:searchFor). Not sure if this still unsafe.


回答1:


I was advised that below query is not safe as parameter :searchFor

You should challenge this advise.

SQL injections occur when the parameter value passed by the client may transmit additional query logic (generally undesirable) and that that will be allowed in the executed query such as.
For example instead of a simple foo textual value for searchFor, the parameter value could contain also additional logic in the query, for example : foo OR ''=''. That is SQL injection.

In your case, SQL injection is not possible because you don't set the parameter manually but rather you rely on a safe way to bind thesearchFor parameter : Spring.
Indeed, Spring binds the parameter values in a safe way as JPA implementations do, that is setting the parameter value from a JPA Query instance that is protected against SQL injections for declared parameters.

For example take this query (I removed the % part to simplify) :

"SELECT u FROM User u WHERE lower(u.username) LIKE :searchFor"

And try to set the param of searchFor with the String "foo OR ''==''" to try to inject a SQL condition that is always true.
If you turn on the log of your JPA implementation to output the paramaters binding (for Hibernate : logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE) you could see something like :

TRACE 11012 --- [nio-8080-exec-8] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [foo OR ''=='']

The binding is only performed for the parameter value and not as a way to add new query logic. The final query part protected is so protected as :

SELECT u FROM User u WHERE lower(u.username) LIKE "foo OR ''==''"



回答2:


I believe underlying ORM framework would sanitate input if passed as parameter this way.



来源:https://stackoverflow.com/questions/55058760/prevent-jpql-query-sql-injection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!