JDBC的SQL注入漏洞
在实现某些业务时,许多SQL语句中的参数都需要通过变量拼接而成,而这些参数大多都是通过用户输入而来,这样就存在了用户恶意输入SQL关键字来影响JDBC中SQL语句的查询。
例如最为常见的登录功能,我们通过用户输入的用户名和密码去检索数据库中的结果,如果存在则登录成功,若不存在则登录失败。
Statement statement = connection.createStatement();
String sql = "SELECT * FROM sys_user WHERE username = '" + username + "' AND password = '" + password + "'";
ResultSet resultSet = statement.executeQuery(sql);
在这种写法中,如果用户恶意将用户名输入为'admin' or 1=1
,无论password输入什么值,只要用户名正确都可以使得该SQL语句能够查询出结果。即拼接后的SQL语句为:
SELECT * FROM sys_user WHERE username = 'admin' or 1 = 1 and password = 'alskdjfeo'
这样就可以在知道用户名的情况下随意登录系统。
因此可以使用PreparedStatement对象对SQL语句进行预编译,并使用占位符来替代要使用的参数,这样能够有效的防止SQL注入。
示例:
package com.jdbc.test;
import com.jdbc.utils.JDBCUtils;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCTest {
@Test
public void login() {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = JDBCUtils.getConnection();
String sql = "select * from sys_user where username = ? and password = ?";
statement = connection.prepareStatement(sql);
statement.setString(1, "Jack");
statement.setString(2, "123456");
resultSet = statement.executeQuery();
if (resultSet.next()) {
System.out.println("登录成功");
} else {
System.out.println("登录失败");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(connection, statement, resultSet);
}
}
}
还没有评论,来说两句吧...