带有#in order by子句的ibatis内联参数

下面是我的ibatis地图配置,

     select * from contact  salary like '%'  order by #orderby#, #orderby2#     

这是我的pojo

 package com.nik; public class Contact { private String firstName; private String lastName; private String email; private String salary; private String mobile; private String orderby; private String orderby2; private int id; public Contact() {} public Contact( String firstName, String lastName, String email) { this.firstName = firstName; this.lastName = lastName; this.email = email; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getSalary() { return salary; } public void setSalary(String salary) { this.salary = salary; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public String getOrderby() { return orderby; } public void setOrderby(String orderby) { this.orderby = orderby; } public String getOrderby2() { return orderby2; } public void setOrderby2(String orderby2) { this.orderby2 = orderby2; } } 

这是我的考试class,

 package com.nik; import com.ibatis.common.resources.Resources; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.client.SqlMapClientBuilder; import java.io.*; import java.sql.SQLException; import java.util.*; import org.apache.log4j.Logger; public class IbatisExample{ public static void main(String[] args) throws IOException,SQLException{ // get a logger instance named "com.foo" Logger logger = Logger.getLogger("com.nik"); Reader reader = Resources.getResourceAsReader("ibatis-config.xml"); SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader); //Output all contacts System.out.println("All Contacts"); Contact c1 = new Contact(); c1.setOrderby("salary"); c1.setOrderby2("mobile"); List contacts = (List) sqlMap.queryForList("Contact.getAll",c1); Contact contact = null; for (Contact c : contacts) { System.out.print(" " + c.getId()); System.out.print(" " + c.getFirstName()); System.out.print(" " + c.getLastName()); System.out.print(" " + c.getEmail()); System.out.print(" " + c.getSalary()); System.out.print(" " + c.getMobile()); contact = c; System.out.println(""); } } } 

这里的问题是order by子句没有效果……

在这里输出

 All Contacts DEBUG [main] - Created connection 71786792. DEBUG [main] - {conn-100000} Connection DEBUG [main] - {pstm-100001} PreparedStatement: select * from contact where salary like '%' order by ?, ? DEBUG [main] - {pstm-100001} Parameters: [salary, mobile] DEBUG [main] - {pstm-100001} Types: [java.lang.String, java.lang.String] DEBUG [main] - {rset-100002} ResultSet DEBUG [main] - {rset-100002} Header: [id, firstName, lastName, email, salary, mobile] DEBUG [main] - {rset-100002} Result: [1, abc, 111, abc@hyahoo.com, 5000, 400] DEBUG [main] - {rset-100002} Result: [2, def, 222, def@yahoo.com, 2000, 100] DEBUG [main] - {rset-100002} Result: [3, xyz, 333, xyz@yahoo.com, 3000, 300] DEBUG [main] - Returned connection 71786792 to pool. 1 abc 111 abc@hyahoo.com 5000 400 2 def 222 def@yahoo.com 2000 100 3 xyz 333 xyz@yahoo.com 3000 300 

如果我在地图配置中用“$”更改“#”(例如,按$ orderby $,$ orderby2 $订购)那么它可以工作,

 All Contacts DEBUG [main] - Created connection 71786792. DEBUG [main] - {conn-100000} Connection DEBUG [main] - {pstm-100001} PreparedStatement: select * from contact where salary like '%' order by salary, mobile DEBUG [main] - {pstm-100001} Parameters: [] DEBUG [main] - {pstm-100001} Types: [] DEBUG [main] - {rset-100002} ResultSet DEBUG [main] - {rset-100002} Header: [id, firstName, lastName, email, salary, mobile] DEBUG [main] - {rset-100002} Result: [2, def, 222, def@yahoo.com, 2000, 100] DEBUG [main] - {rset-100002} Result: [3, xyz, 333, xyz@yahoo.com, 3000, 300] DEBUG [main] - {rset-100002} Result: [1, abc, 111, abc@hyahoo.com, 5000, 400] DEBUG [main] - Returned connection 71786792 to pool. 2 def 222 def@yahoo.com 2000 100 3 xyz 333 xyz@yahoo.com 3000 300 1 abc 111 abc@hyahoo.com 5000 400 

关于为什么带#的内联参数不按顺序工作的任何线索? 我不能使用$,因为这是安全风险,因为强化360 🙁

$var$语法是告诉iBATIS在构造预准备语句之前将var属性的值替换为SQL的唯一方法。 Fortify警告它存在安全风险的原因是,如果直接来自不受信任来源的数据按原样插入到SQL中而没有事先validation,它可以打开SQL注入攻击的大门。

为了防止这样的SQL注入,您可以修改Contact POJO,以便setOrderBysetOrderBy2方法测试它们的参数,并且只有在这些参数在可接受值的集合范围内时才允许设置对象的相应属性。 类似于以下内容:

 public void setOrderBy(String orderBy) { if (orderBy.equals("name") or orderBy.equals(" salary") or orderBy.equals("dept")) { this.orderBy = orderBy; } else { this.orderBy = NULL; } } 

只要您像这样validation所有替换值,使用$var$语法应该是完全可以接受和安全的。

不是一个优雅的解决方案,但我用这个不想做代码更改,