首先来一个用户登录程序
public static void login(String username, String password) {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/tyrantforever";
String sql = "select * from students where stu_name = '" + username + "' and scores = '"+ password +"'";
conn = DriverManager.getConnection(url, "root", "root");
stat = conn.createStatement();
rs = stat.executeQuery(sql);
if(rs.next()) {
System.out.println("用户登陆成功!!!");
}else {
System.out.println("用户登陆失败!!!");
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
if(conn != null) {
conn.close();
}
if(stat != null) {
stat.close();
}
if(rs != null) {
rs.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
如果在main方法里输入
login("张伟", 'hello 'or' 1'='1 ");
输出:
用户登陆成功!!!
分析:
我们将输入sql的语句打印出来:
select * from students where stu_name = '张伟' and scores = 'hello 'or ' 1 '=' 1'
由于数据库解析数据时是从后往前,所以它读到的是
‘1’ = ‘1’ or 。。。。。or前面就为真,所以语句就为真了。
所谓魔高一尺道高一丈,我们自然有防止sql注入的方法
public static void loginWithPrepare(String username, String passwd) {
Connection conn = null;
PreparedStatement stat = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/tyrantforever";
conn = DriverManager.getConnection(url, "root", "root");
String sql = "select * from students where stu_name = ? and stu_no = ?";
stat = conn.prepareStatement(sql);
stat.setString(1, username);
stat.setString(2, passwd);
rs = stat.executeQuery();
if(rs.next()) {
System.out.println("用户登录成功!!!");
}else {
System.out.println("用户登录失败!!!");
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
if(conn != null) {
conn.close();
}
if(stat != null) {
stat.close();
}
if(rs != null) {
rs.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}