网络安全系列 之 SQL注入学习总结

目录

  • 1. sql注入概述
  • 2. sql注入测试工具
  • 3. sql注入防御方法
    • 3.1 问题来源
    • 3.2 防御方法
  • 4. SQL注入防御举例
    • 4.1 使用JDBC时,SQL语句进行了拼接
        • 1. 使用statement的executeQuery、execute、executeUpdate等函数时,传入的SQL语句拼接了来自外部的不可信参数。
        • 2. 使用connection的PreparedStatement时,使用的SQL语句拼接了来自外部的不可信参数。
        • 3. 存储过程使用动态方式构建SQL语句,导致SQL注入风险。
    • 4.2 使用Hibernate时,调用API时,传入的SQL语句有拼接外部参数
        • 1. 调用createQuery时,传入的SQL语句拼接了来自外部的不可信参数。
    • 4.3 使用MyBatis时,SQL语句使用$占位符
        • 1. 配置文件使用$占位符
        • 2. mybatis接口中的函数标签的SQL语句,使用了$占位符

1. sql注入概述

程序里面如果使用了未经校验的外部输入来构造SQL语句,就很可能会引入SQL注入漏洞。

注入攻击
对于字符串输入,如果这个字符串将被解释为某种指令,那么需要特别注意防止注入攻击。sql注入、os命令注入、xml注入是典型的攻击类型。

2. sql注入测试工具

可以使用BurpSuite工具,浏览器上修改代理设置为burp工具配置的代理监听的IP端口。
对浏览器发送的请求进行拦截并修改其中参数,尝试注入攻击。

  • sleep盲注: 返回时间>=5s,存在注入.
    {"stationCodes":"AD02C7CCAB6F4BF9A85BC010AF16AC62')xor(sleep(5))and('","ptIds":"","pmYearDate":"2018","page":1,"pageSize":10}
  • 普通注入or /and : id="1' or '1'='1" id="1' or '1'='2"
  • 报错注入: updatexml /extractvalue 、floor后group by。
  1. id=1 and updatexml(1,concat(0x7e,version(),0x7e),1) 返回version(),存在注入.
  2. id=1 and extractvalue(1,concat(0x7e,version()) 返回version(),存在注入.
  3. id=1 and (select 1 from (select count(),concat(version(),floor(rand(0)2))x from information_schema.tables group by x)a)
    返回version(),存在注入.

3. sql注入防御方法

3.1 问题来源

  1. 执行外部数拼接的SQL语句。
  2. 执行外部传入的整条SQL语句
  3. 在配置文件中的SQL语句没有使用预编译方式占位符。
  4. 校验函数有缺陷或占位符使用错误。

3.2 防御方法

  1. 使用参数化语句
    sql语句预编译绑定变量,不直接拼接。

  2. 输入校验
    采用白名单或黑名单方式对入参进行检查。
    备注:ESAPI(Enterprise Security API)也提供了输入验证类 org.owasp.esapi.reference.DefaultValidator的实现。

  3. 输出编码
    在sql注入语境中,将发送给数据库的内容进行编码(或转义)是必需的操作,可以保证内容被正确的处理。
    针对Mysql的编码举例:在动态sql中提交的信息(LIKE语句中使用通配符的位置)添加引用。

    sql = sql.replace("%",“\%”);   //%匹配0个或多个任意字符
    sql = sql.replace("_",“\_”);    //_匹配任意一个字符

备注:在动态sql和拼接sql场景下也可以利用ESAPI进行转义处理

    // ESAPI转义,防SQL注入
    public static String encodeForSql(String input) {
        MySQLCodec mysqlCodec = new MySQLCodec(MySQLCodec.Mode.STANDARD);
        return ESAPI.encoder().encodeForSQL(mysqlCodec, input);
    }
    // 说明: esapi需要有两个配置文件:ESAPI.properties、validation.properties

小结:输入校验输出编码是处理注入问题(如xss)的一贯套路。

4. SQL注入防御举例

4.1 使用JDBC时,SQL语句进行了拼接

1. 使用statement的executeQuery、execute、executeUpdate等函数时,传入的SQL语句拼接了来自外部的不可信参数。
**错误示例**
    String userName = ctx.getAuthenticatedUserName(); //this is a constant
    //itemName是外部读入的参数拼接到SQL语句
    String sqlString = "SELECT * FROM t_item WHERE owner='" + userName + "' AND itemName='" + request.getParameter("itemName") + "'";
    stmt = connection.createStatement();
    rs = stmt.executeQuery(sqlString);

解决方法 1) 使用预编译方式(不可信数据作为字段值); 2) 对拼接到SQL语句中的外部参数进行白名单校验(不可信数据作为表名,字段名,排序方式)。

**正确示例**:使用白名单校验方式校验itemName
    String userName = ctx.getAuthenticatedUserName(); //this is a constant
    String itemName=getCleanedItemName(request.getParameter("itemName"));
    String sqlString = "SELECT * FROM t_item WHERE owner='" + userName + "' AND itemName='" + itemName + "'";
    stmt = connection.createStatement();
    rs = stmt.executeQuery(sqlString);
2. 使用connection的PreparedStatement时,使用的SQL语句拼接了来自外部的不可信参数。
**错误示例**
    String userName = ctx.getAuthenticatedUserName(); //this is a constant
    //itemName是外部读入的参数拼接到SQL语句
    String itemName = request.getParameter("itemName");
    // ...Ensure that the length of userName and itemName is legitimate
    // ...
    String sqlString = "SELECT * FROM t_item WHERE owner=? AND itemName='"+itemName+"'";

    PreparedStatement stmt = connection.prepareStatement(sqlString);
    stmt.setString(1, userName);
    rs = stmt.executeQuery();

解决方法 1) 将拼接方式改为占位符方式; 2). 对拼接到SQL语句中的外部参数进行白名单校验。

**正确示例**:所有的参数使用占位符
    String userName = ctx.getAuthenticatedUserName(); //this is a constant
    String itemName = request.getParameter("itemName");
    // ...Ensure that the length of userName and itemName is legitimate
    // ...
    String sqlString = "SELECT * FROM t_item WHERE owner=? AND itemName=?";

    PreparedStatement  stmt = connection.prepareStatement(sqlString);
    stmt.setString(1, userName); // jdbc编号从1开始
    stmt.setString(2, itemName);
    rs = stmt.executeQuery();
3. 存储过程使用动态方式构建SQL语句,导致SQL注入风险。
**错误示例**
REATE PROCEDURE sp_queryItem
    @userName varchar(50),
    @itemName varchar(50) 
AS 
BEGIN 
    DECLARE @sql nvarchar(500); 
    SET @sql = 'SELECT * FROM t_item 
                WHERE owner = ''' + @userName + '''
                AND itemName = ''' + @itemName + '''';
    EXEC(@sql); 
END 
GO

解决方法 采用参数化查询的方式

**正确示例**:采用参数化查询的方式
CREATE PROCEDURE sp_queryItem
    @userName varchar(50), 
    @itemName varchar(50) 
AS 
BEGIN 
    SELECT * FROM t_item  
    WHERE userName = @userName
    AND itemName = @itemName; 
END 
GO

4.2 使用Hibernate时,调用API时,传入的SQL语句有拼接外部参数

1. 调用createQuery时,传入的SQL语句拼接了来自外部的不可信参数。
**错误示例**
    //SQL语句拼接不可信参数
    String itemName = request.getParameter("itemName");
    Query hqlQuery = session.createQuery("from Item as item where item.itemName = '" + itemName + "'");
    List<Item> hrs = (List<Item>) hqlQuery.list();

解决方法 1) 对拼接到SQL语句中的外部参数进行白名单校验; 2) 使用hibernate的配置映射关系方式。

**正确示例**:对外部参数进行白名单校验
    String itemName = request.getParameter("itemName");
    itemName=getCleanedItemName(itemName);//白名单校验
    Query hqlQuery = session.createQuery("from Item as item where item.itemName = '" + itemName + "'");
    List<Item> hrs = (List<Item>) hqlQuery.list();

4.3 使用MyBatis时,SQL语句使用$占位符

1. 配置文件使用$占位符
错误示例:
    // 使用$,底层将使用简单拼接    
    <select id="getItems" resultClass="Item">
         SELECT * FROM t_item WHERE owner = $userName$ AND itemName = $itemName$
    </select>

解决方法 1) 将$占位符改为#占位符; 2) 如果外部不可信数据作为表名,字段名,排序方式,则对外部参数进行白名单校验。

**正确示例**:使用#占位符方式
    <select id="getItems" resultClass="Item">
         SELECT * FROM t_item WHERE owner = #userName# AND itemName =#itemName#
    </select>
2. mybatis接口中的函数标签的SQL语句,使用了$占位符
**错误示例**
    public interface IUserDAO { 
     //标注中的SQL语句通过$表示占位符,内部实现是单纯的拼接
    @Select("select *from User where id=${id}) 
        User getUser(@Param("id")String id);
    }
**正确示例**:标注中的SQL语句通过'#'表示占位符,内部实现是参数化预处理
    public interface IUserDAO { 
    @Select("select *from User where id=#{id}) 
       User getUser(@Param("id")String id);
    }

end.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络——不同版本的 HTTP 协议

介绍 HTTP&#xff0c;即超文本传输协议&#xff08;HyperText Transfer Protocol&#xff09;&#xff0c;是应用层的一个简单的请求-响应协议&#xff0c;它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。本文将介绍 HTTP 协议各个版本。 HTTP/1.0 HTTP/1…

Fastapi + vue3 自动化测试平台---移动端App自动化篇

概述 好久写文章了&#xff0c;专注于新框架&#xff0c;新UI界面的实践&#xff0c;废话不多说&#xff0c;开搞 技术架构 后端&#xff1a; Fastapi Airtest multiprocessing 前端&#xff1a; 基于 Vue3、Vite、TypeScript、Pinia、Pinia持久化插件、Unocss 和 Elemen…

FreeRTOS之ARM CR5栈结构操作示意图

FreeRTOS之ARM CR5栈结构操作示意图 1 FreeRTOS源码下载地址2 ARM CR5栈结构操作宏和接口2.1 portSAVE_CONTEXT宏2.1.1 portSAVE_CONTEXT源码2.1.2 portSAVE_CONTEXT宏操作栈结构变化示意图 2.2 portRESTORE_CONTEXT宏2.2.1 portRESTORE_CONTEXT源码2.2.2 portRESTORE_CONTEXT宏…

警惕开源信息成为泄密源头

文章目录 前言一、信息公开需谨慎1、警惕采购招标泄密。2、警惕信息公开泄密。3、警惕社交媒体泄密。 二、泄密风险需严防1、健全制度&#xff0c;明确责任。2、加强管控&#xff0c;严格审查。3、提高意识&#xff0c;谨言慎行。 前言 大数据时代&#xff0c;信息在网络空间发…

指针(上)

目录 内存和地址 指针变量和地址 取地址&#xff08;&&#xff09; 解引用&#xff08;*&#xff09; 大小 类型 意义 const修饰 修饰变量 修饰指针 指针运算 指针- 整数 指针-指针 指针的关系运算 野指针 概念 成因 避免 assert断言 指针的使用 strl…

常见的数据结构---队列、树与堆的深入剖析

目录 一、队列 二、树 三、堆 在现代计算机科学与工程领域&#xff0c;队列、树和堆是三种极其重要的基础数据结构&#xff0c;它们各自具有独特的特点和应用。在日常开发中&#xff0c;合理选择和使用这些数据结构可以显著提高程序的效率和可维护性。它们不仅奠定了算法设计…

Java 整合图片处理相关一套:传输、保存、重命名、删除、AI图片文字识别、图片映射、vue3裁剪、设置黑白色、设置负片、提高照片品质

目录 一、vue3 axios spring boot文件传输 二、Java图片保存到本地 三、Java 本地图片重命名 四、Java 删除本地图片 五、 JavaAI图片文字识别 六、Java映射图片地址&#xff0c;前端直接访问图片 七、vue3 图片裁剪 八、Java 设置图片黑白色 九、Java 设置图片负片 …

web三、 window对象,延时器,定时器,时间戳,location对象(地址),本地存储-localStorage,数组去重new Set

一、 window对象 window对象 是一个全局对象&#xff0c;也可以说是JavaScript中的 顶级对象 像document、alert()、console.log()这些都是window的属性&#xff0c;基本BOM的属性和方法都是window的 所有通过 var定义 在全局作用域中的 变量 、 函数 都会变成window对象的属…

【AI系统】昇腾异构计算架构 CANN

昇腾异构计算架构 CANN 本文将介绍昇腾 AI 异构计算架构 CANN&#xff08;Compute Architecture for Neural Networks&#xff09;&#xff0c;这是一套为高性能神经网络计算需求专门设计和优化的架构。CANN 包括硬件层面的达芬奇架构和软件层面的全栈支持&#xff0c;旨在提供…

Spark和MapReduce场景应用和区别

文章目录 Spark和MapReduce场景应用和区别一、引言二、MapReduce和Spark的应用场景1. MapReduce的应用场景2. Spark的应用场景 三、MapReduce和Spark的区别1. 内存使用和性能2. 编程模型和易用性3. 实时计算支持 四、使用示例1. MapReduce代码示例2. Spark代码示例 五、总结 Sp…

CSS函数

目录 一、背景 二、函数的概念 1. var()函数 2、calc()函数 三、总结 一、背景 今天我们就来说一说&#xff0c;常用的两个css自定义属性&#xff0c;也称为css函数。本文中就成为css函数。先来看一下官方对其的定义。 自定义属性&#xff08;有时候也被称作CSS 变量或者级…

【C语言】递归的内存占用过程

递归 递归是函数调用自身的一种编程技术。在C语言中&#xff0c;递归的实现会占用内存栈&#xff08;Call Stack&#xff09;&#xff0c;每次递归调用都会在栈上分配一个新的 “栈帧&#xff08;Stack Frame&#xff09;”&#xff0c;用于存储本次调用的函数局部变量、返回地…

大数据新视界 -- 大数据大厂之 Hive 数据压缩算法对比与选择(下)(20 / 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

【golang】单元测试,以及出现undefined时的解决方案

单元测试 要对某一方法进行测试时&#xff0c;例如如下这一简单减法函数&#xff0c;选中函数名后右键->转到->测试 1&#xff09;Empty test file 就是一个空文件&#xff0c;我们可以自己写测试的逻辑 但是直接点绿色箭头运行会出问题&#xff1a; 找不到包。我们要在…

ETL工具观察:ETLCloud与MDM是什么关系?

一、什么是ETLCloud ETLCloud数据中台是一款高时效的数据集成平台&#xff0c;专注于解决大数据量和高合规要求环境下的数据集成需求。 工具特点 1.离线与实时集成&#xff1a;支持离线数据集成&#xff08;ETL、ELT&#xff09;和变更数据捕获&#xff08;CDC&#xff09;实…

人形机器人训练、机器臂远程操控、VR游戏交互、影视动画制作,一副手套全部解决!

广州虚拟动力基于自研技术推出了多节点mHand Pro动捕数据手套&#xff0c;其最大的特点就是功能集成与高精度捕捉&#xff0c;可以用于人形机器人训练、机器臂远程操控、VR游戏交互、影视动画制作等多种场景。 一、人形机器人训练 mHand Pro动捕数据手套双手共装配16个9轴惯性…

IDL学习笔记(二)IDL处理卫星数据

IDL处理卫星数据 HDF文件数据集属性通用属性 常用HDF4操作函数常用的HDF5操作函数读取HDF文件的一般步骤 HDF4文件读取-----数据信息查询HDF4文件读取示例-----目标数据TIFF输出提取modis产品中数据&#xff0c;与某一点经纬度最接近的点有效结果&#xff0c;并按每行内容为日期…

动态规划-----路径问题

动态规划-----路径问题 下降最小路径和1&#xff1a;状态表示2&#xff1a;状态转移方程3 初始化4 填表顺序5 返回值6 代码实现 总结&#xff1a; 下降最小路径和 1&#xff1a;状态表示 假设&#xff1a;用dp[i][j]表示&#xff1a;到达[i,j]的最小路径 2&#xff1a;状态转…

Redis+Caffeine 多级缓存数据一致性解决方案

RedisCaffeine 多级缓存数据一致性解决方案 背景 之前写过一篇文章RedisCaffeine 实现两级缓存实战&#xff0c;文章提到了两级缓存RedisCaffeine可以解决缓存雪等问题也可以提高接口的性能&#xff0c;但是可能会出现缓存一致性问题。如果数据频繁的变更&#xff0c;可能会导…

2024年大热,Access平替升级方案,也适合Excel用户

欢迎各位看官&#xff0c;您来了&#xff0c;就对了&#xff01; 您多半是Access忠实粉丝&#xff0c;至少是excel用户&#xff0c;亦或是WPS用户吧。那就对了&#xff0c;今天的分享肯定对您有用。 本文1100字&#xff0c;阅读时长2分50秒&#xff01; 现实总是不尽人意&am…