前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >代码审计 | SQL 注入

代码审计 | SQL 注入

作者头像
TeamsSix
发布2022-09-20 18:35:50
1K0
发布2022-09-20 18:35:50
举报

0x01 JDBC 拼接不当造成 SQL 注入

JDBC 有两种方法执行 SQL 语句,分别为 PrepareStatement 和 Statement,两个方法的区别在于 PrepareStatement 会对 SQL 语句进行预编译,而 Statement 在每次执行时都需要编译,会增大系统开销。

理论上 PrepareStatement 的效率和安全性会比 Statement 好,但不意味着就不会存在问题。

以下是一个使用 Statement 执行 SQL 语句的示例

代码语言:javascript
复制
String sql = "select * from user where id ="+req.getParameter("id");
PrintWriter out = resp.getWriter();
out.println("Statement Demo");
out.println("SQL: "+sql);try {
    Statement st = conn.createStatement();
    ResultSet rs = st.executeQuery(sql);

这里如果输入的 id 为 1 or 1 = 2,那么 SQL 语句就会被拼接为 select * from user where id = 1 or 1 = 2,改变了想要查询 id = 1 的语义。

PreqareStatement 方法支持使用 ? 对变量位进行占位,在预编译阶段填入相应的值会构造出完整的 SQL 语句,从而避免 SQL 注入的产生。

但开发有时为了便利,会直接采取拼接的方式构造 SQL 语句,这样一来依然会存在 SQL 注入,如下代码所示。

代码语言:javascript
复制
String sql = "select * from user where id ="+req.getParameter("id");

PrintWriter out = resp.getWriter();
out.println("prepareStatement Demo");
out.println("SQL: "+sql);try {
    PreparedStatement pst = conn.prepareStatement(sql);
    ResultSet rs = pst.executeQuery();

此时如果使用 or 1 = 1 仍然可以判断存在 SQL 注入,但是如果使用 ? 作为占位符,填入的字段的值就会进行严格的类型检查,就可以有效的避免 SQL 注入的产生,如下代码所示。

代码语言:javascript
复制
PrintWriter out = resp.getWriter();
out.println("prepareStatement Demo");
String sql = "select * from user where id = ?";
out.println(sql);try {
    PreparedStatement pstt = conn.prepareStatement(sql);    // 参数已经强制要求是整型
    pstt.setInt(1, Integer.parseInt(req.getParameter("id")));
    ResultSet rs = pstt.executeQuery();    while (rs.next()){

0x02 框架使用不当造成 SQL 注入

通常框架底层已经实现了对 SQL 注入的防御,但是如果在开发未能恰当的使用框架的情况下,依然会存在 SQL 注入的风险。

1、MyBatis 框架

MyBatis 的思想是将 SQL 语句编入配置文件中,避免 SQL 语句在代码中大量出现,方便对 SQL 语句的修改和配置。

MyBatis 使用 parameterType 向 SQL 语句传参,在 SQL 引用传参的时候可以使用 #{} 和 ${} 两种方式,两种方式区别如下:

${}:SQL 拼接符号,直接将输入的语句拼接到 SQL 语句里,想避免 SQL 注入问题需要手动添加过滤

#{}:占位符号,在对数据解析时会自动将输入的语句前后加上单引号从而避免 SQL 注入

也就是说在 MyBatis 框架中,如果使用了 ${} 方法,同时又没有进行过滤就会产生 SQL 注入,而使用 #{} 方法时可以避免 SQL 注入。

2、Hibernate 框架

Hibernate 是现今主流的 Java 数据库持久化框架,采用 Hibernate 查询语句(HQL)注入。

HQL 查询语句来自 Hibernate 引擎进行解析,因此产生的错误可能来自数据库,也有可能来自 Hibernate 引擎。

HQL 和 SQL 的区别:

HQL 注入和 SQL 注入的成因都一样,使用拼接 HQL 语句的写法可能会导致 SQL 注入

代码语言:javascript
复制
Query query = session.createQuery("from User where name='"+queryString+"'");

但是受语法影响,HQL注入在漏洞利用上有一定的限制,比如不能利用联合查询、不能跨库查表、执行命令等。

对于 Hibernate 的注入,这里只作为简单了解一下,平时代审的时候注意一下即可。


往期推荐

代码审计 | Java Web 过滤器 - filter

代码审计 | Java Web 核心技术 - Servlet

代码审计 | Java EE 基础知识

参考文章: https://www.redhatzone.com/ask/article/1448.html https://blog.csdn.net/qq_36594628/article/details/119461996 原文链接: https://www.teamssix.com/211117-091653.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-11-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 TeamsSix 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x01 JDBC 拼接不当造成 SQL 注入
  • 0x02 框架使用不当造成 SQL 注入
    • 1、MyBatis 框架
      • 2、Hibernate 框架
      相关产品与服务
      代码审计
      代码审计(Code Audit,CA)提供通过自动化分析工具和人工审查的组合审计方式,对程序源代码逐条进行检查、分析,发现其中的错误信息、安全隐患和规范性缺陷问题,以及由这些问题引发的安全漏洞,提供代码修订措施和建议。支持脚本类语言源码以及有内存控制类源码。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档