前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JDBC 通过PreparedStatement 解决SQL注入(5)

JDBC 通过PreparedStatement 解决SQL注入(5)

作者头像
桑鱼
发布2020-03-17 16:48:02
1.7K0
发布2020-03-17 16:48:02
举报

常见的SQL注入

  1. 数字注入

在浏览器地址栏输入:test.com/sql/article.php?id=1,这是请求方式为get的接口,发送这个请求相当于调用一个查询语句

$sql = "select * from article where id = ",$id

正常情况下,应该返回id=1的文章信息,但是,如果在浏览器地址栏输入test.com/sql/article.php?id=-1 OR 1 = 1,这就是一个SQL注入攻击了,可能会返回所有文章的相关信息。产生这种情况的原因是,id=-1 永远是false,1=1永远是true,所以整个where语句永远是true,相当于没有加where条件,所以查询的条件相当于是整张表的内容

  1. 字符串注入

常见的用户登录场景:输入用户名和密码,提交。

这是一个post请求,登录时调用接口test.com/sql/login.html,sql的查询过程:首先连接数据库,然后后台对post请求参数中的用户名、密码进行参数校验。假如此时输入用户名和密码为user和123456,提交,相当于调用了以下的SQL语句:

select * from user where username = 'user' and password = '123456'

1)用户名输入:user'#,密码随意输入,如:111,然后提交。此时SQL语句是:

select * from user where username = 'user'#' and assword = '111'

#后面被注释了,实际执行的sql是:

select * from user where username = 'user'

2)用户名输入:user'--,密码随意输入,如:111

select * from user where username = 'user'--' and assword = '111'

--后面被注释了,实际执行的sql是:

select * from user where username = 'user'

PreparedStatement 防止SQL注入

  1. PreparedStatement是Statement的子接口,可以传入带占位符的SQL语句,并且提供了补充占位符变量的方法。
  2. PreparedStatement能最大可能提高性能:DBServer会对预编译语句提供性能优化。因为预编译语句有可能被重复调用,所以语句在被DBServer的编译器编译后的执行代码被缓存下来,那么下次调用时,只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中就会得到执行。但在Statement语句中,即使是相同操作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意义,实事实是没有数据库会对普通语句编译后的执行代码缓存,这样每执行一次都要对传入的语句编译一次。
代码语言:javascript
复制
class MyTest{
    // 更新 删除 添加
    public void testPreparedStatement(){
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mydb";
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try{
            connection = DriverManager.getConnection(url,"root", "root");
            String sql = "Insert into customers(name,email,birth) values(?,?,?)"
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,"test");
            preparedStatement.setString(2,"test@qq.com");
            preparedStatement.setString(2,"test@qq.com");
            preparedStatement.setDate(3,new Date(new java.util.Date().getTime()));
            preparedStatement.executeUpdate();
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            preparedStatement.close();
            connection.close();
        }
    }
    // 查询
    public void testPreparedStatement01(){
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mydb";
        String username = "user";
        String password = "123456"
        String sql = "select * from users where username = ?" + "and password = ?"
        Connection connection = null;
        PreparedStatement preparesStatement = null;
        ResultSet resultSet = null;
        try{
            conncection = DriverManager.getConnection(url,"root", "root");
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,username);
            preparedStatement.setString(2,password);
            resultSet = preparedStatement.executeQuery();
            if(resultSet.next()){
              System.out.println("success");
            }else{
              System.out.println("fail");
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            resultSet.close();
            preparedStatement.close();
            connection.close();
        }
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 常见的SQL注入
  • PreparedStatement 防止SQL注入
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档