首页 > 数据库 >Java代码审计-SQL注入

Java代码审计-SQL注入

时间:2024-08-04 19:26:29浏览次数:14  
标签:审计 语句 Java SQL 编译 sql 注入

Java代码审计-SQL注入

前言

今天学习了java代码中导致的sql注入的相关知识,浅浅的记录一下。

一、SQL注入简介

SQL 注入是因为程序未能正确对用户的输入进行检查,将用户输入以拼接的方式带入 SQL 语句中,影响原 SQL 语句的逻辑,导致了 SQL 注入的产生。

SQL 注入漏洞可能会造成服务器的数据库信息泄露、数据被窃取、网页被篡改,甚至可能会造成网站被挂马服务器被远程控制、被安装后门等。

二、Java主要执行SQL语句的方式

1.JDBC

JDBC是Java连接数据库的标准API。它提供了一组接口和类,用于与关系型数据库进行交互。通过JDBC,可以连接到各种数据库(如MySQL、Oracle、SQL Server等),执行SQL语句、事务管理和结果集处理等操作。

2.MyBatis

ORM框架,允许将Java对象和关系型数据库之间进行映射,进而实现数据库操作。

Mybatis 是一个持久层框架,它封装数据连接、获取结果集等一系列的繁琐操作,使用者只需关注操作 SQL 语句的编写,通过 xml 或注解的方式就能将数据库中的数据与对象形成映射进行返回。

Mybatis 的学习曲线相对较低,适合对 SQL 有深入理解的开发者。

3.Hibernate

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将java对象与数据库表建立映射关系,是一个全自动的orm框架。

Hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。

Hibernate 的学习曲线较高,需要理解其 ORM 模型和配置。

三、JDBC方式产生的漏洞

1.Statement方式

java.sql.Statement 是 Java JDBC 下执行 SQL 语句的一种原生方式,执行语句时需要通 过拼接来执行。若拼接的语句没有经过过滤,将出现 SQL 注入漏洞。

//采用拼接的方式 
String sql = "select * from user where id = "+req.getParameter("id"); 
 Statement st = con.createStatement(); //创建Statement对象
 ResultSet rs = st.executeQuery(sql); //执行查询

由上述代码可以看到,该方式只是对前端用户输入直接进行sql语句的拼接,然后代入数据库查询,可导致SQL注入漏洞。

2.PreparedStatement方式

PreparedStatement 会预处理 SQL 语句,为原本需要拼接的参数参数保留一个问号(?)作为占位符。

采用预编译的方式,可以有效地防止SQL注入漏洞。

//sql语句如下  使用?代替之前需要拼接的参数
String sql = "select * from user where id = ?"; 
PreparedStatement pstt = con.prepareStatement(sql); //对sql语句进行预编译
pstt.setInt(1,Integer.parseInt(req.getParameter("id"))); //对里面的参数进行设置 可以理解成将id转换为int后放到第一个?的位置
 ResultSet rs = pstt.executeQuery();//执行查询

像上述这样正确使用预编译的操作是比较安全的,可以有效防止SQL注入。

那么,预编译防止SQL注入怎么做的呢?

  • 对下面代码,输入" 小明’ ",经过测试发现是对特殊符号加入转义字符。
String sql = "select * from user where name = ?";  // sql语句
PreparedStatement st = conn.prepareStatement(sql);  //预编译
st.setString(1, "小明'"); // 参数赋值 sql注入测试
System.out.println(st.toString()); //输出为:select * from user where name = '小明\''

那么,使用预编译的方法就完全避免注入的影响了嘛?、

  • 答案是否定的。

经过测试发现,预编译不会对%进行转移,这正好是SQL语句like查询需要的。

假如代码如下所示,则会遇到SQL注入的风险。

String sql = "select * from user where name like ?";  // 含有参数 
st = conn.prepareStatement(sql);
st.setString(1, "%小明%" + "%"); // 参数赋值
System.out.println(st.toString()); //输出为select * from user where name like '%小明%%'

这样就改变了原本查询的意思。

另外,预编译也不会对_进行转义

那么,还有个问题,就是不是所有的语句都能够使用预编译来解决的。

  • 比如代码中使用order by语句时,这种特殊情况无法使用预编译。order by 子句后面需要加字段名或者字段位置,而预编译后产生的是字符串,不再是字段名,这种情况下只能使用sql语句拼接的办法。
  • 所以使用这些特殊语句时,要注意对输入进行过滤。

四、MyBatis方式产生的漏洞

1.两种参数符号造成的SQL注入

MyBatis支持两种参数符号,一种是#,另一种是$。

  • 当使用#时,MyBatis底层会使用预编译的机制。
  • 使用参数符号$时,MyBatis底层直接用字符串拼接把参数和SQL语句拼接在一起,然后执行。

2.order by、like、in引发注入

  • 与第三部分的描述类似,在mybatis中使用order by语句的话,只能使用参数符号$,即使用字符串拼接的方式,如果没有进行严格过滤,则导致注入。
  • like in 同理

五、Hibernate方式产生的漏洞

1.简介

  • HQL注入:Hibernate中没有对数据进行有效的验证导致恶意数据进入应用程序中造成的。与SQL注入类似。

2.原理

与第三部分、第四部分类似。

参数绑定,这样是安全的

String queryString = "from Item item where item.deion like :searchString”;

List result = session.createQuery(queryString).setString("searchString", searchString).list();

直接拼接是不安全的。

HQL注入利用比较有限。

六、总结

综上所述,主要是考虑代码是否使用了预编译,以及对于一些未使用预编译的特殊语句,是否进行了安全的校验。

参考

标签:审计,语句,Java,SQL,编译,sql,注入
From: https://blog.csdn.net/qq_44780157/article/details/140808552

相关文章

  • Java代码审计-命令执行
    Java代码审计-命令执行前言一、漏洞简介二、命令连接符三、ProcessBuilder命令执行1.ProcessBuilder简介2.漏洞利用四、Runtimeexec命令执行1.Runtimeexec简介2.漏洞利用五、探索1.代码底层原理2.疑问3.小结六、总结参考前言今天来学一下java代码审计中的命令......
  • 2--Web前端开发-JavaScript
    引入方式1、内部脚本:将JS代码定义在HTML页面中JavaScript代码必须位于<script></script>标签之间在HTML文档中,可以在任意地方,放置任意数量的<script>一般会把脚本置于<body>元素的底部,可以改善显示速度<script>alert("hellojavascript");</script>可放在代码中任意位......
  • navicat-mysql重置密码
    目录navicat-mysql重置密码1.Mysql8.0以下2.navicatformysql出现如下问题1.问题描述2.查看用户信息3.问题原因4.解决问题navicat-mysql重置密码1.Mysql8.0以下搜索命令提示符,以管理员身份进入。输入scquerymysql找到Mysql服务名称,然后输入netsotpmysql80(这个是sc......
  • Hive SQL必刷练习题:同时在线人数问题(*****)
    https://blog.csdn.net/Mikkkee/article/details/136776193  --DropDROPTABLEIFEXISTStest_live_events;--DDLCREATETABLEIFNOTEXISTStest_live_events(user_idINTCOMMENT'用户id',live_idINTCOMMENT'直播id'......
  • mysql常用的查询
    mysql常用的查询建表末尾必加上ENGINE=InnoDBDEFAULTCHARSET=utf8跨表一列比较,多列查询SELECTsno,cno,rankfromscoreJOINgradeonscore.degree>low&&score.degree<upp;模糊查询,字符转化的筛选查询,分组统计查询SELECTcnofromscoreWHERECAST(cnoASchar)L......
  • 详细教程 MySQL 数据库 下载 安装 连接 环境配置 全面
    数据库就是储存和管理数据的仓库,对数据进行增删改查操作,其本质是一个软件。首先数据有两种,一种是关系型数据库,另一种是非关系型数据库。关系型数据库是以表的形式来存储数据,表和表之间可以有很多复杂的关系,比如:MySQL、Oracle、SQLServer等;非关系型数据库是以数据集的形式存......
  • Java流程控制语句结构--分支结构
    目录if语句switch语句三元运算符(条件运算符)总结Java中的分支结构是程序设计中用于根据条件选择不同执行路径的重要机制。它允许程序在运行时根据特定条件来决定执行哪一部分代码。Java中的分支结构主要包括以下几种:if语句基本形式:if(条件表达式){语句块;}如果条件表达式......
  • Java流程控制语句结构--循环结构
    目录while循环do…while循环for循环三种循环的死循环形式while循环while是最基本的循环,它的结构为:while(布尔表达式(判断条件)){//循环内容}只要布尔表达式为true,循环就会一直执行下去。do…while循环对于while语句而言,如果不满足条件,则不能进入循环。但有时候我......
  • Java流程控制04:循环结构
    顺序结构的程序语句只能被执行一次。如果您想要同样的操作执行多次,就需要使用循环结构。Java中有三种主要的循环结构:while循环do…while循环for循环1.while循环while是最基本的循环,它的结构为:while(布尔表达式){//循环内容}只要布尔表达式为true,循环就会一......
  • Java流程控制05:break & continue
    1.break关键字break主要用在循环语句或者switch语句中,用来跳出整个语句块。break跳出最里层的循环,并且继续执行该循环下面的语句。【演示:跳出循环】publicstaticvoidmain(String[]args){ inti=0; while(i<100){ i++; System.out.println(i); if(i==......