【JDBC】SQL注入攻击演示与解决方法

    xiaoxiao2023-03-24  4

    <pre name="code" class="java">import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /* SQL注入攻击演示 */ public class Demo1 { public static void main(String[] args) throws ClassNotFoundException, SQLException { new Demo1().select(); } public void select() throws ClassNotFoundException, SQLException{ Class.forName("com.mysql.jdbc.Driver"); String url="jdbc:mysql://localhost:3306/jdbc"; String user="root"; String password="root"; Connection connection=DriverManager.getConnection(url, user, password); /* 利用字符串拼接时单引号成对出现的规律, 与MySQL关系型运算符and的优先级高于or, 与MySQL查询语句的格式综合形成的漏洞, 在输入的密码上做手脚-> */ String id="1001"; //输入账户ID String pw="2' or '1'='1"; //输入密码。巧妙地在查询语句之后增加了一段 String sqlCode="select * from t_login where userId="+id+" and password='"+pw+"'"; //sqlCode结果:select * from t_login where userId='1001' and password='2' or '1'='1'; // -> (true/false and false) or true -> true //等同于:select * from t_login where true; --输出所有语句 //------------------------------------- Statement st=connection.createStatement();//可以改进的代码... ResultSet rs= st.executeQuery(sqlCode); //------------------------------------- //简单输出 if(rs.first()){ do{ System.out.print(rs.getInt(1) +"\t"); System.out.print(rs.getString(2) +"\t"); System.out.println(); }while(rs.next()); }else{ System.out.println("登录信息不正确,登陆失败!"); } /* 当用户ID和密码正确输入时的结果:返回表中该用户的账户ID与密码 1001 123456 当受到注入攻击输出结果:输出了该表中所有用户的账户密码信息。 1001 123456 1002 233333 1003 888888 1004 666666 */ rs.close(); st.close(); connection.close(); } }

    防止注入攻击的改进方法:使用PreparedStatement

    将上述被//------标记的两行代码替换为如下代码:

    PreparedStatement st=connection.prepareStatement("select * from t_login where userid=? and password=?"); st.setString(1, id); st.setString(2, pw); ResultSet rs=st.executeQuery();//注意:换方法了,没有传参当受到注入攻击输出结果:登录信息不正确,登陆失败!

    转载请注明原文地址: https://ju.6miu.com/read-1201085.html
    最新回复(0)