简单谈一谈 Java 中的预编译

本文最后更新于 2019.12.01,总计 1174 字 ,阅读本文大概需要 2 ~ 5 分钟
本文已超过 655天 没有更新。如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!

目录

0x01 预编译机制

在java中JDBC中,我们写 SQL 语句的时候,有个预处理功能,这个功能一大优势就是能提高执行速度,尤其是多次操作数据库的情况,再一个优势就是预防SQL注入,严格的说,应该是预防绝大多数的SQL注入。

如下示例代码即为Java中 JDBC 的预处理:

String sql = "select * from t_student where name = ? and content = ?"
try {
    PreparedStatement ps = conn.prepareStatement(sql);
    ps.setString(1,name);
    ps.setString(2,content);
    ps.executeUpdate(sql_update);
}catch(Exception e){
    e.printStackTrace();
}

那么这个预编译的功能,到底是如何防止 SQL 注入的呢?

0x02 预编译的原理

其实是因为,SQL语句在代码运行前,已经进行了预编译。在程序运行时第一次操作数据库之前,SQL语句已经被数据库分析,编译和优化,然后对应的执行计划也会缓存下来并允许数据库已参数化的形式进行查询。

当运行时,JDBC动态地把参数传给PreparedStatement时,即使参数里有敏感字符,如: ' or ' 1' = '1 updatexml(2,concat(0x7e,(version())),0)等,preparedStatement 会对入参中的关键字进行转义,比如单引号转义成\',其流程大致如下:

image-20191127215556085.png

总之,简单来说,JDBC在处理SQL语句时有一个预编译的过程,而预编译对象就是把一些格式固定的SQL编译后,存放在内存池中即JDBC缓冲池,当我们再次执行相同的SQL语句时就不需要预编译的过程了,所以即使SQL注入特殊的语句,也会只当做参数传进去,不会当做指令执行

0x03 参考

https://blog.csdn.net/aidupo6157/article/details/101981536

https://blog.csdn.net/theorytree/article/details/7331096

「感谢老板送来的软糖/蛋糕/布丁/牛奶/冰阔乐!」

panda

(๑>ڡ<)☆谢谢老板~

使用微信扫描二维码打赏

版权属于:

panda | 热爱安全的理想少年

本文链接:

https://cnpanda.net/sec/589.html(转载时请注明本文出处及文章链接)

添加新评论

暂无评论