很多情况因为过滤不严导致很多网站存在sql注入,这里以用户登陆为例,简单举例
首先创建一个测试的数据库
比较基础,不写创建过程了
java代码如下:
packagecn.basic.jdbc;importjava.awt.image.RescaleOp;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;importorg.junit.jupiter.api.Test;public classTest1 {/** public static void main(String[] args) throws ClassNotFoundException,
* SQLException { login("aa","aa"); }*/@Testpublic void testlogin() throwsClassNotFoundException, SQLException {
login("aa", "aa");
}public static void login(String username, String password) throwsSQLException, ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
Connection conn= DriverManager.getConnection("jdbc:mysql://127.0.0.1/test", "root", "root");
Statement st=conn.createStatement();
String sql= "select * from xxx where username=" + "'" + username + "'" + "and password=" + "'" +password+ "'";
ResultSet rs=st.executeQuery(sql);if(rs.next()) {
System.out.println("恭喜" + username + "登陆成功");
System.out.println(sql);
}else{
System.out.println("登录失败");
}if (rs != null) {
rs.close();
}/** if (st != null) { st.close(); }*/
if (conn != null) {
conn.close();
}
}
}
运行
输入正确账号密码可以登陆成功。这里可以被绕过。
很显然这是万能密码。那么如何去修复sql注入呢,这里比较好的方法是采用预编译的开发方式,这是个开发习惯问题。
修复后的预编译代码如下:
packagecn.basic.jdbc;importjava.awt.image.RescaleOp;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;importorg.junit.jupiter.api.Test;public classTest1 {/** public static void main(String[] args) throws ClassNotFoundException,
* SQLException { login("aa","aa"); }*/@Testpublic void testlogin() throwsClassNotFoundException, SQLException {
login("aa", "aa");
}public static void login(String username, String password) throwsSQLException, ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
Connection conn= DriverManager.getConnection("jdbc:mysql://127.0.0.1/test", "root", "root");
String sql="select * from xxx where username=? and password=?";//使用预编译
PreparedStatement ps =conn.prepareStatement(sql);
ps.setString(1, username);
ps.setString(2, password);
ResultSet rs=ps.executeQuery();if(rs.next()) {
System.out.println("恭喜" + username + "登陆成功");
System.out.println(sql);
}else{
System.out.println("登录失败");
}if (rs != null) {
rs.close();
}if(ps!=null) {
ps.close();
}/** if (st != null) { st.close(); }*/
if (conn != null) {
conn.close();
}
}
}
再来测试下是否存在安全漏洞:
输入正确密码:
尝试万能密码绕过:
这里杜绝了sql注入的产生,在很多时候,要养成用预编译编方式实现增删改查,这里以查询为例子,增删改同理!
预编译并不代表百分百防止sql注入的,这只是一种防止sql注入的措施。
不忘初心,方得始终。