# 概念
服务器上的数据库运行非法的 SQL 语句,主要通过拼接来完成。
# 攻击原理
例如一个网站登录验证的 SQL 查询代码为:
strSQL = "SELECT * FROM users WHERE (name = '" + userName + "') and (pw = '"+ passWord +"');"
1
如果填入以下内容:
userName = "1' OR '1'='1";
passWord = "1' OR '1'='1";
1
2
2
那么 SQL 查询字符串为:
strSQL = "SELECT * FROM users WHERE (name = '1' OR '1'='1') and (pw = '1' OR '1'='1');"
1
此时无需验证通过就能执行以下查询:
strSQL = "SELECT * FROM users;"
1
# 防范手段
# 1. 使用参数化查询
Java 中的 PreparedStatement 是预先编译的 SQL 语句,可以传入适当参数并且多次执行。由于没有拼接的过程,因此可以防止 SQL 注入的发生。
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM users WHERE userid=? AND password=?");
stmt.setString(1, userid);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
1
2
3
4
2
3
4
# 2. 单引号转换
将传入的参数中的单引号转换为连续两个单引号,PHP 中的 Magic quote 可以完成这个功能。