预编译后SQL注入仍旧存在

admin 2022年5月29日14:39:56评论285 views字数 1199阅读3分59秒阅读模式

一、什么是预编译



普通sql语句执行过程:提交SQL语句 -> 数据库引擎对SQL语句进行编译得到数据库可执行的代码 -> 执行SQL代码;

预编译:SQL语句发送给DBMS,由DBMS首先进行编译后再执行。预编译语句和Statement不同,在创建PreparedStatement 对象时就指定了SQL语句,该语句立即发送给DBMS进行编译。当该编译语句被执行时,DBMS直接运行编译后的SQL语句,而不需要像其他SQL语句那样首先将其编译。


二、Jdbc预编译、框架Mybatis预编译



1.Jdbc预编译

Jdbc预编译

String sql = "SELECT * FROM user WHERE id = '" + id + "'";

Statement statement = connection.createStatement();

statement.execute(sql);


String sql = "SELECT * FROM user WHERE id = ?";

//预编译语句

PreparedStatement preparedStatement = connection.prepareStatement(sql);

//填入参数

preparedStatement.setString(1,reqStuId);

preparedStatement.executeQuery();

 构造请求 /?id='or 1 #  预编译的不会出现问题,执行的SQL会变成 SELECT * FROM user WHERE id = ''or 1 #'

2.框架Mybatis预编译

直接拼接写法

SELECT * FROM student WHERE stu_id = ${stuId}


预编译写法

SELECT * FROM student WHERE stu_id = #{stuId}

三、存在的问题



预编译对ORDER BY子句、表名、列名不生效。

通过占位符传参,不管传递的是什么类型的值,都会被单引号包裹。而使用 ORDER BY 时,要求传入的是字段名或者是字段位置,传入的是引号包裹的字符串,那么 ORDER BY 会失效,如:SELECT * FROM user ORDER BY 'id'

类似的, GROUP BY 也会有同样的问题。最后引用下P师傅总结

预编译后SQL注入仍旧存在

MyBatis 预编译模式的实现,在底层同样是依赖于 java.sql.PreparedStatement,所以 PreparedStatement 存在的问题,这里也会存在。


四、参考链接

https://mp.weixin.qq.com/s/l2Bt9jv-96HapqxYfeju2w

https://www.huaweicloud.com/articles/0613297d897534a6322641e0b3d30ff8.html

https://github.com/langligelang/dragonfly


原文始发于微信公众号(赛博少女):预编译后SQL注入仍旧存在

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年5月29日14:39:56
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   预编译后SQL注入仍旧存在http://cn-sec.com/archives/820318.html

发表评论

匿名网友 填写信息