Hibernate : How to prevent SQL injection when the collection elements needs to check with `like` operator?

ぃ、小莉子 提交于 2019-12-24 03:12:29

问题


I am having a query something like this.

StringBuilder sbQry = new StringBuilder();
sbQry.append("select * from tableName where 1=1");
if(!myCollection.isEmpty()){
    sbQry.append("  and (");
        for (int i = 0; i < myCollection.size(); i++) {
            final String module = myCollection.get(i);
            sbQry.append("column = '" + module
                    + "' or column like 'J_'||'"
                    + module.replaceAll("-", "%") + "'");
            if (!(i == (myCollection.size() - 1))) {
                sbQry.append(" or ");
            }
        }
        sbQry.append(") ");
 }

Here this query sbQry is vulnerable to SQLInjection because of myCollection is coming from the external source.

In case my collection elements would be comparing based on = operator then I use prepared statement, something like:

sbQry.append(column in (:collection));
Query query = session.createSQLQuery(sbQry.toString());
query.setParameterList("collection",myCollection);

Could anyone please suggest me how can I prevent the SQL injection in this case.

Any help will be appreciated.


回答1:


To protect against SQL injection, you should use bound parameters, not string interpolation.

StringBuilder sbQry = new StringBuilder();
List<String> params = new ArrayList<>();
sbQry.append("select * from tableName");
if(!myCollection.isEmpty()){
    sbQry.append(" where ");
    int size = myCollection.size;
    List<String> terms = new ArrayList<>();
    for (int i = 0; i < size; i++) {
        final String module = myCollection.get(i);
        terms.add("column = ? or column like ?");
        params.add(module);
        params.add("J_" + module.replaceAll("-", "%"));
    }
    sbQry.append(String.join(" or ", terms));
}

Query q = sess.createQuery(sbQry);
int size = params.size();
for (int i = 0; i < size; i++) {
    q.setString(i, params[i]);
}

I have not tested the above code, but it should give you the general idea.

Using bound parameters instead of string concatenation is a safe way to protect against SQL injection, and it also makes code easier to write and easier to read.

Also using ArrayList for the terms, and String.join(), means you don't have to fuss with 1=1 or special conditional code for the beginning or end of the series of terms.



来源:https://stackoverflow.com/questions/49512493/hibernate-how-to-prevent-sql-injection-when-the-collection-elements-needs-to-c

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