JCBD - 7 - JCBD-Mysql注入问题

sql注入问题

写在前面! 别把数据库名 数据库密码   和  sql语句的用户名 和 sql语句的 用户密码混淆!!!

 

Tips:原判断sql语句:String sql = "select id,name,password,email,birthday from t_user where name='" + username + "' and password='" + password + "'";

在之前写的登录功能中,随便输入一个用户名,在密码部分输入下面内容:

123' or 1='1

这个密码肯定是不正确的,但是依然能够登录成功,这个就是sql注入问题,也就是说之前写的登录功能有安全问题。为什么会导致这样的问题?我们将最终执行的sql打印可以看到是这样的:

select id,name,password,email,birthday from t_user where name='tb' and password='123' or 1='1';

出现问题的部分是 or 1=’1’这部分,因为无论如何这部分的运算结果都是true,所以在输错用户名和密码的情况下依然登录成功了。要想解决这个问题,可以使用jdbc提供的PreparedStatement。

 

大概意思就是说 SQL语句的拼接出问题了  主要还是 or x = x  这段是true的 所以会登录成功!  那我们怎么去修复呢:

 

我们不用 Statement 了  用 PreparedStatement 这玩意

 

PreparedStatement

PreparedStatement是一个接口,它继承了Statement,该接口有以下几个优点:

  • 性能比Statement高,会把sql预编译
  • 可以解决sql注入问题

使用PreparedStatement修改登录功能的代码:

第一就是将 你要 将要防SQL注入的语句要传入的字段将他改为?(英文状态下的问号):

String sql = "select id,name,password,email,birthday from t_user where name=? and password=?";    //name=?  password=?

第二就是将 Statement  改为 PreparedStatement 类,并且调用prepareStatement方法将存在占位符(?)的sql语句当做参数传过去:

PreparedStatement stmt = conn.prepareStatement(sql);                      //注意调用的是 connection类下的prepareStatement()方法  没有d的啊 是 prepare

第三就是调用PreparedStatement类下的 setString方法填补指定的占位符(?) 即:将?的字段填上:

setString这个方法有两个参数 :

参1: 第几个占位符(?) 下标从1开始 , 参2:填补的内容。 例:

stmt.setString(1, name);    //第一个占位符啊  即name  这里将变量name作为补充 填补进去

stmt.setString(2, password);    //第二个占位符啊  即password  这里将变量password  作为补充 填补进去

 

在sql语句中,使用?作为占位符来替代要传入的内容,通过调用PreparedStatement的setString等方法将要传入的内容作为参数传递过去。

 

TIPS! 当你执行查询 executeQuery() 語句時 别带参数( Sql语句)!

 //!这个executeQuery语句不要带参数!记住!!因为前面已经把它用prepareStatement方法传进去了。
            ResultSet QueryResult = preparedStatement.executeQuery();  //然后方可和之前的方式一样调用execute各个执行语句.
//            ResultSet QueryResult = preparedStatement.executeQuery(Sql_Login);  //错误例子啊! 之前一直找不到哪里出问题...

...烦死.

 

posted @ 2021-05-14 17:46  咸瑜  阅读(66)  评论(0编辑  收藏  举报