深入了解Java中的SQL注入

news2024/12/24 3:14:38

深入了解Java中的SQL注入

本文以代码实例复现了Java中JDBC及Mybatis框架采用预编译和非预编译时可能存在SQL注入的几种情况,并给予修复建议。

JDBC

首先看第一段代码,使用了远古时期的JDBC并且并没有使用预编译。这种简单的字符串拼接就存在SQL注入

@RequestMapping("/jdbc/vuln")
public String jdbc_sqli_vul(@RequestParam("username") String username) {

    StringBuilder result = new StringBuilder();

    try {
        Class.forName(driver);
        Connection con = DriverManager.getConnection(url, user, password);

        if (!con.isClosed())
            System.out.println("Connect to database successfully.");

        // sqli vuln code
        Statement statement = con.createStatement();
        String sql = "select * from users where username = '" + username + "'";
        logger.info(sql);
        ResultSet rs = statement.executeQuery(sql);

        while (rs.next()) {
            String res_name = rs.getString("username");
            String res_pwd = rs.getString("password");
            String info = String.format("%s: %s\n", res_name, res_pwd);
            result.append(info);
            logger.info(info);
        }
        rs.close();
        con.close();


    } catch (ClassNotFoundException e) {
        logger.error("Sorry,can`t find the Driver!");
    } catch (SQLException e) {
        logger.error(e.toString());
    }
    return result.toString();
}

简单复现下
在这里插入图片描述

再看第二段代码,这段代码也是使用了JDBC但使用了PreparedStatement预编译,这回就避免了SQL注入

@RequestMapping("/jdbc/sec")
    public String jdbc_sqli_sec(@RequestParam("username") String username) {

        StringBuilder result = new StringBuilder();
        try {
            Class.forName(driver);
            Connection con = DriverManager.getConnection(url, user, password);

            if (!con.isClosed())
                System.out.println("Connecting to Database successfully.");

            // fix code
            String sql = "select * from users where username = ?";
            PreparedStatement st = con.prepareStatement(sql);
            st.setString(1, username);

            logger.info(st.toString());  // sql after prepare statement
            ResultSet rs = st.executeQuery();

            while (rs.next()) {
                String res_name = rs.getString("username");
                String res_pwd = rs.getString("password");
                String info = String.format("%s: %s\n", res_name, res_pwd);
                result.append(info);
                logger.info(info);
            }

            rs.close();
            con.close();

        } catch (ClassNotFoundException e) {
            logger.error("Sorry, can`t find the Driver!");
            e.printStackTrace();
        } catch (SQLException e) {
            logger.error(e.toString());
        }
        return result.toString();
    }

但是这种预编译在某些情况并不能使用

like模糊查询

例如在使用like进行模糊查询的时候,我们对第二段代码的sql进行修改

select * from users where username like '%?%'

预编译报错

在这里插入图片描述

order by

在order by的情况中也不能使用预编译,因为会将进行排序的字段名解析为字符串导致无法正常排序

若强行预编译

select * from users order by ?

数据库数据如下

在这里插入图片描述

我想根据username进行排序则需要以下sql

select * from users order by username

成功执行顺序是对的

在这里插入图片描述

但是强行预编译会将sql解析成

select * from users order by 'username'

在这里插入图片描述

排序错误导致失去作用
在这里插入图片描述

in

正常情况下的where in

select * from users where id in (1,2,3)

在这里插入图片描述

若强行预编译

select * from users where id in ?

导致结果报错

select * from users where id in '(1,2,3)'

在这里插入图片描述

mybatis

mybatis与hibernate等框架同样存在这些问题,hibernate现在很少用以mybatis为例

Mapper注解未使用占位符预编译存在SQL注入

 @Select("select * from users where username = '${username}'")
 List<User> findByUserNameVuln01(@Param("username") String username);

在这里插入图片描述

Mapper xml未使用占位符预编译存在SQL注入

<select id="findByUserNameVuln02" parameterType="String" resultMap="User">
	select * from users where username like '%${_parameter}%'
</select>

在这里插入图片描述

Mapper xml在排序时未采用占位符预编译存在SQL注入

<select id="findByUserNameVuln03" parameterType="String" resultMap="User">
	select * from users
	<if test="order != null">
    	order by ${order} asc
	</if>
</select>

在这里插入图片描述

安全的mybatis代码

@Select("select * from users where username = #{username}")
User findByUserName(@Param("username") String username);
<select id="findById" resultMap="User">
	select * from users where id = #{id}
</select>
<select id="OrderByUsername" resultMap="User">
	select * from users order by id asc limit 1
</select>

修复

1.可以的话对参数进行类型转换,数字型注入很少出现大多都是字符串拼接

Interge.valueof()

2.占位符预编译,目前最有效的办法

3.like,order by,where in需要特殊处理

例如:

处理like

select * from user where username like concat('%', ?, '%')

处理order by

可以做白名单处理sql

/**
     * 过滤mybatis中order by不能用#的情况。
     * 严格限制用户输入只能包含<code>a-zA-Z0-9_-.</code>字符。
     *
     * @param sql sql
     * @return 安全sql,否则返回null
     */
private static final Pattern FILTER_PATTERN = Pattern.compile("^[a-zA-Z0-9_/\\.-]+$");
    public static String sqlFilter(String sql) {
        if (!FILTER_PATTERN.matcher(sql).matches()) {
            return null;
        }
        return sql;
    }

也可以在java层面做映射处理,例如限制用户输入1或2不同数字对应不同的排序

处理in

可以使用Mybatis自带循环指令解决SQL语句动态拼接的问题

select * from users where id in
	<foreach collection="ids" item="item" open="("separator="," close=")">
		#{item} 
	</foreach>

SQL注入排查

可以使用专用的安全扫描工具也可以进行手动排查

关键字:Select、Dao 、from 、delete 、update、insert

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/66203.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一云七芯!ZStack 祝贺上海市金融信创联合攻关基地荣获一等奖

2022年11月初&#xff0c;由上海市总工会、中共上海市经济和信息化工作委员会、上海市经济信息化委员会主办的2022上海城市数字化转型 “智慧工匠”选树、“领军先锋”评选活动信创应用竞赛决赛暨颁奖典礼中&#xff0c;“一云七芯适配验证云平台及服务解决方案”获得信创应用案…

GitHub2022年度前100的Java面试真题高频知识点汇总

前言 这是我在工作、面试中学习并总结到的一些知识点&#xff0c;都是一些比较典型的、面试常常被问到的问题。 如果你平时没有注意去总结的话&#xff0c;那么当你面试被问到的时候可能会是一脸懵圈&#xff0c;就算这个问题你知道怎么回事&#xff0c;但是你平时没有认真总…

【win11内存占用高优化】未运行程序,系统内存占用50以上

这里写自定义目录标题前言打开控制面板找到电源键功能找到快速启动选项&#xff0c;取消勾选&#xff0c;确定win X以管理员身份打开powershell输入如下命令&#xff0c;回车关闭终端完成前言 windows11在未运行任何其他程序的情况下&#xff0c;内存占用超50%&#xff0c;可…

速度收藏,Fiddler详细使用教程出炉!

目录 01、抓取不同类型接口数据 02、数据模拟以及过滤规则 03、如何模拟接口响应数据 04、使用fiddler进行评论接口测试 绵薄之力【软件测试学习资源分享】 01、抓取不同类型接口数据 查看windows本机的IP 配置fiddler 需要保证要抓取的手机与电脑保持同一网段&#xff0…

转换 FLAC、APE 无损音乐格式为 iTunes 支持导入的 M4A 格式

大家知道常见的无损音乐格式有 FLAC、APE、WAV 等这些格式。其中 FLAC (Free Lossless Audio Codec) 格式因为是免费自由的压缩编码、无损压缩&#xff0c;且受到操作系统、软件及硬件的广泛支持。所以是非常流行常见的无损音乐格式。 自 2005 年 Mac OS X v10.4 开始&#xf…

《垃圾回收算法手册 自动内存管理的艺术》——其他分区策略(笔记)

文章目录十、其他分区策略10.1 大对象空间10.1.1 转轮回收器10.1.2 在操作系统支持下的对象移动10.1.3 不包含指针的对象10.2 基于对象拓扑结构的回收器10.2.1 成熟对象空间的回收10.2.2 基于对象相关性的回收10.2.3 线程本地回收10.2.4 栈上分配10.2.5 区域推断10.3 混合标记—…

磨金石教育摄影技能干货分享|传统民居摄影作品欣赏

我们知道在绘画领域有写实和写意之分&#xff0c;写实多用于人像的描绘&#xff0c;写意多用于山水田园画的创作。尤其是在中国传统绘画艺术中&#xff0c;写意简直就是创作的精髓。 写实和写意的区别在于&#xff0c;前者侧重真实还原&#xff0c;后者在于主管情感表达。 建筑…

哈希表、哈希桶(C++实现)

1. 哈希 1.1 概念 哈希&#xff08;hash&#xff0c;中文&#xff1a;散列&#xff1b;音译&#xff1a;哈希&#xff09;&#xff0c;是一种算法思想&#xff0c;又称散列算法、哈希函数、散列函数等。哈希函数能指导任何一种数据&#xff0c;构造出一种储存结构&#xff0c…

机器学习笔记之配分函数(二)——随机最大似然

机器学习笔记之配分函数——随机最大似然引言回顾&#xff1a;对数似然梯度关于∇θL(θ)\nabla_{\theta}\mathcal L(\theta)∇θ​L(θ)的简化基于MCMC求解负相关于书中图像的解释引言 上一节介绍了对包含配分函数的概率分布——使用极大似然估计求解模型参数的梯度(对数似然…

5款高效率,但是名气不大的小众软件

今天推荐5款十分小众的软件&#xff0c;但是每个都是非常非常好用的&#xff0c;用完后觉得不好用你找我。 1.多窗口文件整理——Q-Dir Q-Dir 是一款多窗口文件整理工具&#xff0c;特别适合用户频繁在各个文件夹中跳转进行复制粘贴的文件归档操作。如果你的电脑硬盘中文件已经…

MySQL 数据库的增删查改 (2)

文章目录一. 数据库约束1. 约束类型2.NULL 约束3.UNIQUE 约束4.DEFAULT 约束5. PRIMARY KEY 约束6.FOREIGN KEY 约束二.表的设计三.插入四.查询1.聚合查询2.联合查询3.合并查询本篇文章继承与 MySQL 表的增删改查(1) 一. 数据库约束 1. 约束类型 NOT NULL -- 表示某一行不能…

下载安全证书到jdk中的cacerts证书库

最近在公司遇到访问https请求&#xff0c;JDK返回异常信息的问题。返回如下&#xff1a; java.lang.Exception: java.lang.Exception: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: u…

废弃阶段的风险评估

概述 风险评估应贯穿于评估对象生命周期 各阶段中。评估对象生命周期各阶段中涉及的风险评估原则和方法昆一致的&#xff0c;但由干各阶段实施内容对象、安全需求不同.使得风险评估的对象、目的、要求等各方面也有所不同。在规划设计阶段&#xff0c;通过风险评估以确定评估对…

线程安全介绍

线程安全 多线程程序处于一个多变的环境当中&#xff0c;可访问的全局变量和堆数据随时都可能被其他的线程改变。因此多线程程序在并发时数据的一致性变得非常重要。 竞争和原子操作 多个线程同时访问一个共享数据&#xff0c;可能造成很恶劣的后果。下面是一个著名的例子&a…

多数之和问题

文章目录多数求和问题1两数之和(无序)题解2两数之和(有序)题解3两数之和(二叉搜索树)题解4 三数之和题解5四数之和题解多数求和问题 针对给一组用例,和一个目标数target,求用例中多数相加等于target的所有数,且不能重复问题,一般有两种解法: 集合(不要求排序)双指针(要求排序…

万德L2接口代码执行工作的过程分享

在设计万德L2接口时&#xff0c;避免不了要用到 一些代码&#xff0c;今天小编来给各位分享一下万德L2接口代码执行工作的过程分享&#xff1a; 这里只分享部分功能执行的过程&#xff1a; OrderQueueRecord&#xff08;委托队列&#xff09; 字段名 类型 备注 stock_ex…

word文档

WORD行与行中间空出一行&#xff0c;怎么办&#xff1f; 这个情况又分两种情况&#xff1a; 第①种情况&#xff1a;行与行之间的空白行都多了一个回车符&#xff1a; Word中&#xff0c;当我们从网络上复制一些文本或者是拿到一些别人的文本&#xff0c;这种文本经常会有大…

自动切换背景的登录页面

自动切换背景的登录页面 有趣的小案例池子&#xff1a; JS实现定时器 JS实现关闭图片窗口 JS实现输入检验 获取焦点后隐藏提示内容的输入框 JS实现获取鼠标在画布中的位置 聊天信息框显示消息 JS点击切换背景图 自动切换背景的登录页面 JS制作跟随鼠标移动的图片 JS实现记…

电脑提示ISDone.dll错误怎么办?

在安装一些大型游戏时&#xff0c;容易出现ISDone.dll错误&#xff0c;那么这时我们该怎么办呢&#xff1f; 出现ISDone.dll错误的原因&#xff1f; ① RAM或硬盘空间不足&#xff0c;或内存和硬盘出现故障。 ② ISDone.dll和Unarc.dll文件损坏或丢失。 ③ 系统文件损坏。 …

JAVA基于局域网的聊天室系统(源代码+论文)

毕业论文 局域网聊天室系统的设计与实现 论文作者姓名&#xff1a;申请学位专业&#xff1a;申请学位类别&#xff1a;指导教师姓名&#xff08;职称&#xff09;&#xff1a;论文提交日期&#xff1a; 基于局域网的视频聊天室系统的设计与实现 摘 要 视频聊天系统作为一种…