SQL注入
昨天做了一张卡,是用于解决SQL注入问题的。现在就把昨天学到和用到的内容总结一下吧:)
1. 什么是SQL注入
简单的说,SQL注入是一种攻击行为,恶意的向SQL语句中插入某些内容进而达到某些不好的目的。
举个例子吧,就是:
statement = "SELECT * FROM users WHERE name =‘" + userName + "‘;"
这条语句的本意是检索出叫某个名字的用户的信息;
可是如果有人恶意的传入
‘ or ‘1‘ = ‘1
那么这条语句就被搞成:
statement = "SELECT * FROM users WHERE name =‘‘ or ‘1‘ = ‘1‘
此时这条语句会检索出所有用户的信息。
SQL注入好像还有一些话说,但是我们就简单的先理解到这里吧。
2. 如何解决SQL注入--prepared statement
有那么几种可以解决SQL注入的方法,其中我们比较常用的就是prepared statement, prepared statement又称为parameterized statement。
prepared statement设计的本意是用于高效的重复执行一些相同或相似的SQL语句。
他通常采用模板的形式并且于运行时替代某几个变量。
DBMS对于prepared statement的处理流程是这样的:
首先,SQL语句的模板会最早发送到DBMS,其中有未指定的参数,也称为占位符。比如
INSERT INTO PRODUCT (name, price) VALUES (?, ?)
其次,DBMS会对这个模板进行解析、编译、以及一系列的最优化运算;保存结果但并不执行。
最后,DBMS根据拿到的具体参数执行SQL语句。
由此我们可以看到使用prepared statement有这样两个优点:
首先,无论需要执行多少次这个SQL语句,都只需要对其进行一次解析、编译与优化处理,因此提高了性能。
其次,使用prepared statement可以避免SQL injection,这是由于在对prepared statement模板中的参数进行替换时,会进行类型与转义字符的检查。
Java JDBC中,prepared statement这样用:
java.sql.PreparedStatement stmt = connection.prepareStatement( "SELECT * FROM users WHERE USERNAME = ? AND ROOM = ?"); stmt.setString(1, username); stmt.setInt(2, roomNumber); stmt.executeQuery();
4. ibatis中如何解决SQL注入
当使用ibatis时,有两种方式向SQL中加入参数,第一种是使用#parameter#,
<select id="getItems" parameterClass="MyClass" resultClass="items"> SELECT * FROM items WHERE owner = #userName# </select>
使用#则相当于隐式的使用了prepared statement,也就是安全的方式
第二种是使用$parameter$,是一种不安全的方式。
<select id="getItems" parameterClass="MyClass" resultClass="items"> SELECT * FROM items WHERE owner = #userName# AND itemname = ‘$itemName$‘ </select>