首页 > 代码库 > SQL注入

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>