Using prepared statement for Order by to prevent SQL injection java

跟風遠走 提交于 2019-12-08 07:39:15

问题


I have a query with where conditions , order by and limit. I am using prepared statements to set the where conditions and limit. Currently i am using string append for order by which causing SQL injection vulnerability.

I cannot use set string to order by like this order by ? ? SQL Order functionality not working if i do like this.

Example query:

SELECT siteid, technology, address, state, status FROM archive  LEFT OUTER 
JOIN mappings ON siteid = child_site_id order by siteid asc limit ? offset ?


SELECT siteid, technology, address, state, status FROM archive  LEFT OUTER 
JOIN mappings ON siteid = child_site_id order by siteid asc limit 10 offset 0

Any other way i can do this to avoid SQL injection.


回答1:


Do something like this and concatenate it:

List<String> allowedSortableColumns = Arrays.asList(new String[]{"siteid", "technology", "address"})
if(! allowedSortableColumns.contains(sortByColumn)){
   throw new RuntimeException("Cannot sort by: " + sortByColumn);
}
// Continue here and it's safe to concatenate sortByColumn...

You can do sanitization and other stuff, but this should work in your case




回答2:


You should use a whitelist of possible columns:

String[] cols = {"siteid", "technology", "address", "state", "status"};

then use an index when referring to columns with the user:

int colFromUser = Integer.parseInt(request.getParameter("sortCol"));

and validate the index before appending the column name to the order by list:

if(colFromUser < 0 || colFromUser >= cols.length) {
    throw new IllegalArgumentException("Invalid column");
}
String col = cols[colFromUser];
query.append(col);

Although if it was me, I'd be using something like Hibernate criteria to do this job:

Criteria c2 = session.createCriteria(Supplier.class);
c2.addOrder(Order.desc("name"));



回答3:


PreparedStatement SetMethods are applicable only for database table column values ( WHERE clause values for SELECT & DELETE SQL statements and also includes to be updated or inserted column values for UPDATE & INSERT statements).

So this means that following usual SQL parts like - column names , table schema , table name , ORDER BY , GROUP BY , Pagination ( LIMIT , OFFSET , FETCH FIRST etc ) can't be parametrized via question mark symbol ( ? ) of java.sql.PreparedStatement

Directly appending values from user input to query will cause security flaw and only way out is to examine input values from your list of valid values for these sections of SQL.

e.g. what table name you are expecting ? , what schema should be for a particular table ? , what columns are present in a particular table ? , is page number an integer ?, is LIMIT value an integer ? values after column names for ORDER BY clause should only be ASC or DESC & nothing else etc etc.

You can either dynamically populate these valid values or hard code in systems.

If invalid value is passed then either we don't execute query ( & log it as error ) or replace invalid value with useful defaults and execute query.



来源:https://stackoverflow.com/questions/48504315/using-prepared-statement-for-order-by-to-prevent-sql-injection-java

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