文章目录

Javaweb-数据库操作-模式&写法&预编译等环境搭建JDBC 注入分析关于预编译

Mybatis 注入分析Hibernate 注入分析总结:

Javaweb-代码审计SQL注入-INXEDU在线网校

Javaweb-数据库操作-模式&写法&预编译等

环境搭建

VulDemo审计源码百度云 在Java中执行SQL语句一般有以下几种方式:

JDBC 注入分析

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);

while (rs.next()){

out.println("
Result: "+ rs.getObject("name"));

}

} catch (SQLException throwables) {

throwables.printStackTrace();

}

这里sql语句与请求参数进行了拼接(使用了JDBC API Statement执行sql语句的方法)

PrintWriter out = resp.getWriter();

out.println("prepareStatement Demo3");

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()){

out.println("
id: "+rs.getObject("id"));

out.println("
name: "+rs.getObject("name"));

}

} catch (SQLException throwables) {

throwables.printStackTrace();

}

PreparedStatement(也是JDBC API执行sql语句的方法)

Statement和PreparedStatement是Java JDBC API中两种常用的执行SQL语句的方式 Statement: Statement对象用于执行静态SQL语句,即在编译时已经确定了SQL语句的结构。 Statement执行SQL语句时,直接将完整的SQL语句发送给数据库执行。 Statement对象适用于执行不带参数的简单SQL查询或更新操作。 由于Statement对象没有预编译阶段,每次执行SQL语句时都需要将SQL语句编译一次,这可能导致一定的性能开销。 由于没有参数化输入的机制,使用Statement对象时需要谨慎处理输入数据,以防止SQL注入攻击。 PreparedStatement: PreparedStatement对象用于执行动态SQL语句,即在执行时才确定SQL语句的具体参数值。 PreparedStatement对象在创建时需要提供一个SQL模板,其中的参数使用占位符(例如,“?”)表示。 在执行PreparedStatement时,首先会对SQL语句进行编译和优化,然后只需提供参数值,而不需要重新编译SQL语句。 PreparedStatement适用于频繁执行带有参数的SQL语句,如参数化查询。 由于PreparedStatement具有预编译和参数化输入的特性,可以提高性能和安全性,并且能够防止SQL注入攻击。

安全写法(SQLDemo3): “select * from user where id = ?”; //参数化执行sql语句 不安全写法(SQLDemo): “select * from user where id =”+req.getParameter(“id”);

关于预编译

编译器在编译sql语句时,会依次进行词法分析、语法分析、语义分析等操作, 预编译技术会让数据库跳过编译阶段(sql语句已经编译好了),也就无法就进行词法分析,关键字不会被拆开,所有参数 直接 变成字符串 进入 数据库执行器执行。 参考:https://blog.csdn.net/qq_42521154/article/details/110785392

Mybatis 注入分析

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

以下方式可以防御SQL注入

#号会点语句进行预编译 ${ } 只是进行string 替换,动态解析SQL的时候会进行变量替换

安全写法(): select * from user where name = #{name} 不安全写法(UserDao.xml):select * from user where name = ${name}

#{name}和${name}是MyBatis中两种常用的参数传递方式,具有不同的行为和特点

#{name}(参数占位符):

是一种安全的参数传递方式,会自动进行参数值的转义和处理,防止SQL注入攻击

使用#{name}时,MyBatis会将参数值作为预编译的参数,将其安全地插入到SQL语句中。

-----------------------------------------------------------------------------

${name}(文本替换):

${name} 是一种简单的文本替换方式,它会将 ${name} 直接替换为参数值,不进行参数值的转义或处理。

使用${name}时,参数值会被直接拼接到SQL语句中,存在SQL注入的风险。

Hibernate 注入分析

PrintWriter out = resp.getWriter();

out.println("Hibernate Demo");

try {

tx = session.beginTransaction();

String parameter = req.getParameter("name");

// List user = session.createQuery("FROM User where name='" + parameter + "'").getResultList();

// from user where name = 'Yu or 1=1'

Query query = session.createQuery("from com.demo.bean.User where name = ?1", User.class);

query.setParameter(1, parameter);

List user = query.getResultList();

for (Iterator iterator =

user.iterator(); iterator.hasNext(); ) {

User user1 = (User) iterator.next();

out.println(user1.toString());

}

tx.commit();

}catch (HibernateException e) {

if (tx!=null) tx.rollback();

e.printStackTrace();

}finally {

//session.close();

}

安全写法():参数绑定预编译 Query.query=session.createNativeQuery(“select * from user where name=:name”); query.setParameter(“name”,parameter) ; 这里对’进行了转义;通过query.setParameter()方法将参数值设置到查询语句中,避免了直接拼接参数值到查询语句中的安全风险 不安全写法(User.java): Query.query=session.createNativeQuery(“select * from user where name=”+req.getParameter(“id”)); 这里同样也是拼接

总结:

1、预编译使用不当: sql=“select * from user where id = ?”; sql+=“and username =”+req.getParameter(“username”); 2、直接动态拼接: “select * from user where id =”+req.getParameter(“id”); 3、order by& like & in查询:(由于这两种不能预编译,所以需要过滤器或自定义过滤) 防御: 能预编译的情况都做预编译,一些特殊无法做预编译的,则过滤用户可控的参数。

Javaweb-代码审计SQL注入-INXEDU在线网校

思路:明确SQL三种模式->引用Mybatis->$()写法及XML文件->deleteArticleByIds->ArticleService.java->调用层次结构->deleteArticle->this.deleteArticle(aridArr) 路由:/admin/article/delete 参数:articelId

python sqlmap.py -r inxedu.txt

POST /admin/article/delete HTTP/1.1

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

Accept-Encoding: gzip, deflate, br

Accept-Language: zh-CN,zh;q=0.9

Cache-Control: max-age=0

Connection: keep-alive

Cookie: BEEFHOOK=AOWdyRnbQnsrIpDhPuZf0a8oGzFzUKJrfRgGVHbRCB8cvznVuMjwWpmCPpPZuQyYjmiKPdtWLQJWbF80; _c_id=ascxsky7fw6uja985fn1635787683950vota; 3AB9D23F7A4B3C9B=YRQ5UHLXN2L3Z6RWJYHZNC3APNTMAJZNYXER2ILC6Z6TLFUDUAWZ4TLJA54Q37AMAKWGGT4LWNSNWYAUH6UJWZU74E; jSkQ_2132_ulastactivity=dcc8oerh%2F%2BcUSRVNiDd1%2B3wanKhoUM6O1jjHGfOa8wi1oDWf7zW5; jSkQ_2132_lastcheckfeed=1%7C1638707571; jSkQ_2132_nofavfid=1; JSESSIONID=12705DA8E13D05312443DE7F337F512F; inxedulogin_sys_user_=inxedulogin_sys_user_1

Host: 127.0.0.1:8080

Sec-Fetch-Dest: document

Sec-Fetch-Mode: navigate

Sec-Fetch-Site: none

Sec-Fetch-User: ?1

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36

sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101"

sec-ch-ua-mobile: ?0

sec-ch-ua-platform: "Windows"

articelId=1*

相关阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。