代码审计-Java项目&JDBC&Mybatis&Hibernate&注入&预编译&写法

文章目录

  • 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语句的方法)
代码审计-Java项目&JDBC&Mybatis&Hibernate&注入&预编译&写法_第1张图片

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 注入分析

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.demo.dao.UserDao">
    <select id="QueryByName" parameterType="String" resultType="com.demo.bean.User">

        select *  from user where name = ${name}
    </select>
    以下方式可以防御SQL注入
    <select id="QueryByName" parameterType="String" resultType="com.demo.bean.User">

        select *  from user where name = #{name}
    </select>
</mapper>

#号会点语句进行预编译
${ } 只是进行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) ;
代码审计-Java项目&JDBC&Mybatis&Hibernate&注入&预编译&写法_第2张图片
这里对’进行了转义;通过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*

你可能感兴趣的:(JAVA安全,java,mybatis,hibernate)