SQL注入常见攻击点与防御详解

SQL注入是一种非常常见且危险的Web安全漏洞。攻击者通过将恶意的SQL代码插入到应用程序的输入参数中,欺骗后端数据库执行这些非预期的命令,从而可能窃取、篡改、删除数据或获得更高的系统权限。

以下是详细、准确的SQL注入点分类、说明及举例:

一、 按注入点位置分类

1. GET 参数注入
  • 描述: 通过URL中的查询字符串(即?后面的参数)进行注入。这些参数通常用于GET请求,如过滤、搜索、分页等。

  • 原理: 参数值被直接拼接到SQL查询中,未经过滤或转义。

  • 举例

    • 正常URL: https://example.com/products.php?id=1

    • 对应SQL: SELECT * FROM products WHERE id = 1

    • 攻击URL: https://example.com/products.php?id=-1' UNION SELECT username, password FROM users -- -

    • 最终SQL: SELECT * FROM products WHERE id = -1' UNION SELECT username, password FROM users -- -

    • 解释: id=-1确保原查询不返回结果,UNION SELECT用于窃取用户表数据,-- -用于注释掉原查询的剩余部分。

2. POST 参数注入
  • 描述: 通过POST请求的正文(Body)进行注入。常见于登录表单、搜索框、注册等任何用户提交数据的场景。

  • 原理: 与GET注入类似,只是数据通过请求体传输,不在URL中显示。

  • 举例(登录表单):

    • 正常输入: 用户名 admin,密码 secret

    • 对应SQL: SELECT * FROM users WHERE username = 'admin' AND password = 'secret'

    • 恶意输入: 用户名 admin' --,密码 任意值

    • 最终SQL: SELECT * FROM users WHERE username = 'admin' -- ' AND password = '任意值'

    • 解释: --注释掉了密码验证部分,使攻击者能以admin身份登录,无需知道密码。

3. Cookie 注入
  • 描述: 应用程序将Cookie值(如user_idsession_id)直接用于数据库查询而未经验证。

  • 原理: 攻击者通过修改自己的Cookie值为恶意Payload来实现注入。

  • 举例

    • 正常Cookie: user_id=5

    • 对应SQL: SELECT * FROM users WHERE user_id = 5

    • 恶意Cookie: user_id=5 UNION SELECT @@version

    • 最终SQL: SELECT * FROM users WHERE user_id = 5 UNION SELECT @@version

    • 解释: 攻击者通过修改Cookie,联合查询了数据库的版本信息。

4. HTTP 头部注入
  • 描述: 应用程序将HTTP请求头部的值(如User-AgentX-Forwarded-ForReferer)记录到数据库或用于查询。

  • 原理: 攻击者在这些头部字段中构造恶意Payload。

  • 举例(记录User-Agent到数据库):

    • 正常User-Agent: Mozilla/5.0 ...

    • 对应SQL: INSERT INTO access_log (user_agent) VALUES ('Mozilla/5.0 ...')

    • 恶意User-Agent: Mozilla/5.0 ...', (SELECT @@version)) --

    • 最终SQL: INSERT INTO access_log (user_agent) VALUES ('Mozilla/5.0 ...', (SELECT @@version)) -- ')

    • 解释: 攻击者将数据库版本信息注入到了access_log表中。

二、 按注入技术(漏洞成因)分类

1. 基于联合查询(UNION-based)
  • 描述: 利用UNIONUNION ALL操作符将恶意查询结果附加到原始查询之后,从而在应用程序响应中直接显示数据。

  • 前提: 需要知道原始查询的列数(通过ORDER BYUNION SELECT NULL试探)以及各列的数据类型。

  • 举例: 如上文GET参数注入的例子。

2. 基于错误(Error-based)
  • 描述: 故意构造Payload使数据库报错,并从错误信息中提取敏感数据(如数据库结构、数据内容)。即使页面不回显查询结果,但会回显错误信息时,此方法有效。

  • 举例(MySQL):

    • Payload: id=1' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT @@version),0x3a,FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a) --

    • 解释: 此Payload利用MySQL的RAND()GROUP BY子句制造一个重复键错误,并将@@version信息包含在错误信息中返回。

3. 基于布尔盲注(Boolean Blind)
  • 描述: 当页面没有数据回显和错误回显,但会根据SQL查询结果为真或为假返回不同的页面状态(如“存在”/“不存在”、“正常”/“404”)时使用。

  • 原理: 通过构造逻辑判断(如AND 1=1AND 1=2)观察页面差异,逐位(bit)猜测数据。

  • 举例(猜测数据库名长度):

    • id=1' AND (SELECT LENGTH(database())) = 8 --

    • 如果页面返回正常,说明当前数据库名长度为8;如果返回异常(或无结果),则不是8。然后继续猜测每个字符是什么。

4. 基于时间盲注(Time Blind)
  • 描述: 当页面没有任何回显(包括错误和布尔差异)时使用。通过构造Payload,根据查询条件的真假让数据库执行延时操作,通过观察页面响应时间来判断条件真假。

  • 原理: 利用数据库的延时函数(如MySQL的SLEEP()BENCHMARK(),PostgreSQL的pg_sleep())。

  • 举例(MySQL,猜测数据库名首字母):

    • id=1' AND IF(SUBSTRING(database(),1,1)='a', SLEEP(5), 0) --

    • 如果页面响应延迟了5秒,说明数据库名的第一个字母是'a';否则不是。

5. 堆叠查询(Stacked Queries)
  • 描述: 利用分号;在一次数据库调用中执行多条SQL语句。这允许执行任意SQL命令,而不仅仅是查询。

  • 前提: 后端数据库驱动需要支持多语句执行(如PHP中的mysqli_multi_query(),而mysql_query()不支持)。

  • 举例

    • id=1'; DROP TABLE users; --

    • 解释: 此Payload会先执行原始查询,然后立即执行DROP TABLE users语句删除用户表。

6. 二次注入(Second-Order)
  • 描述: 一种更隐蔽的注入。恶意Payload首先被存储到数据库中(例如,在注册用户名时注入),当时并未触发。之后,当应用程序从数据库取出该数据并用于另一个SQL查询时,注入才被触发。

  • 原理: 输入在第一次插入时可能被转义,但存储后被认为是“干净”的数据,第二次使用时未经过滤。

  • 举例

    1. 注册阶段: 攻击者注册一个用户,用户名为 admin' --

      • 插入SQL: INSERT INTO users (username) VALUES ('admin'' -- ') (经过转义,安全)

    2. 后续操作: 管理员在后台查看用户列表,程序执行: SELECT * FROM users WHERE username = 'admin' -- '

      • 解释: 从数据库取出的用户名admin' --被直接拼接进新的查询,注释掉了后续条件,可能导致列出所有用户或其他敏感操作。

三、 其他特定场景的注入点

1. 搜索功能(LIKE子句)
  • 描述: 搜索框通常使用LIKE '%keyword%',这里的引号和百分号是常见的注入点。

  • 举例

    • 正常输入: apple

    • SQL: SELECT * FROM products WHERE name LIKE '%apple%'

    • 恶意输入: %' UNION SELECT 1,2,3 --

    • 最终SQL: SELECT * FROM products WHERE name LIKE '%%' UNION SELECT 1,2,3 -- %'

2. ORDER BY 子句注入
  • 描述: ORDER BY后面通常接列名或列索引,不能直接使用UNION。但可以利用IF语句或 CASE WHEN 进行盲注。

  • 举例(盲注):

    • https://example.com/products?sort=IF(1=1, name, price)

    • https://example.com/products?sort=IF((SELECT SUBSTRING(@@version,1,1))='5', name, price)

    • 解释: 通过IF条件控制排序依据的列,观察排序结果的不同来判断条件真假。

3. 宽字节注入
  • 描述: 主要针对使用GBK、BIG5等宽字符集的PHP应用程序。由于转义函数(如addslashesmagic_quotes_gpc)和字符集编码配合不当,导致转义符\%5C)被“吃掉”,从而使得单引号逃逸。

  • 原理: 攻击者输入一个特殊字符(如%bf%27),%bf与转义符%5c组合成一个合法的宽字符(如),从而使后面的单引号%27成功逃逸。

  • 举例

    • 输入: id=%bf%27

    • 转义后: %bf%5c%27 (PHP的addslashes'转义为\'%5c%27)

    • 数据库以GBK解码: %bf%5c 被解码为汉字“縗”,剩下的 %27(单引号)则留在原地,成功闭合了查询。

总结与防御

防御原则(永远不要信任用户输入)

  1. 使用参数化查询(预编译语句): 这是最有效、根本的防御手段。将SQL代码与数据完全分离,用户输入永远被视为数据,而非代码。几乎所有编程语言和框架(如Java的PreparedStatement, PHP的PDO, Python的sqlite3)都支持。

  2. 使用ORM框架: 如Hibernate, Entity Framework,它们通常内置了参数化查询。

  3. 最小权限原则: 数据库账户不应拥有过高权限(如DROP, FILE权限)。

  4. 输入验证和过滤: 对输入进行严格的白名单验证(如只允许字母数字)。但绝不能仅依赖此方法。

  5. 转义: 如果万不得已必须拼接SQL,必须使用数据库特定的转义函数(如mysql_real_escape_string),但要注意字符集问题(宽字节注入)。

  6. 错误处理: 向用户展示友好的错误页面,而不是详细的数据库错误信息。

通过了解这些常见的注入点和攻击技术,开发者和安全人员可以更有针对性地进行代码审计和安全防护。

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

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

相关文章

EKSPod 资源利用率配置修复:从占位符到完整资源分析系统

概述 在 Kubernetes 集群管理过程中,资源利用率的监控和优化是保证应用性能和成本效益的关键环节。近期,我们对 EKSPod 管理界面的资源利用率显示功能进行了全面修复,将原先简单的占位符文本升级为完整的资源分析系统。本文将详细介绍这次修复的背景、方案、实现细节和最终…

Linux内核(架构)

文章目录Linux内核架构概述核心子系统详解1、进程管理2、内存管理3、虚拟文件系统(VFS)4、设备驱动模型掌握Linux内核核心技术阶段1:基础准备阶段2:内核基础阶段3:深入子系统阶段4:高级主题(持续学习)调试和…

基于数据挖掘的单纯冠心病与冠心病合并糖尿病的证治规律对比研究

标题:基于数据挖掘的单纯冠心病与冠心病合并糖尿病的证治规律对比研究内容:1.摘要 背景:冠心病和冠心病合并糖尿病在临床上较为常见,且二者在证治方面可能存在差异,但目前相关系统研究较少。目的:对比基于数据挖掘的单纯冠心病与冠…

即梦AI快速P图

原图: 模型选择3.0效果比较好,提示词“根据提供图片,要求把两边脸变小,要求把脸变尖,要求眼妆变淡,眼睛更有神,要求提亮面部肤色要求面部均匀,面部要磨皮!鼻头高光和鼻翼两边阴影变淡…

【办公类-109-04】20250913圆牌卡片(接送卡被子卡床卡入园卡_word编辑单面)

背景需求: 为了发被子,我做了全校批量的圆形挂牌,可以绑在“被子包”提手上,便于再操场上发放被子时,很多老师可以协助根据学号发放。 https://blog.csdn.net/reasonsummer/article/details/149755556?spm=1011.2415.3001.5331https://blog.csdn.net/reasonsummer/arti…

Shoptnt 促销计算引擎详解:策略模式与责任链的完美融合

在电商系统中,促销计算是业务逻辑最复杂、变更最频繁的模块之一。它不仅需要处理多种促销类型(满减、折扣、优惠券等),还要管理它们之间的优先级和互斥关系。 Shoptnt 设计了一套基于 策略模式 (Strategy Pattern) 和 责任链模式…

【HTTP 请求格式】从请求行 到 请求体

引言 在前后端开发中,前端和后端之间的交互主要依赖于 HTTP(HyperText Transfer Protocol,超文本传输协议)。HTTP 是互联网通信的基础,它定义了客户端(通常是浏览器或App)和服务器之间如何交换数…

【自记】SQL 中 GROUPING 和 GROUPING SETS 语句的案例说明

我们用一个生活中的例子来理解,比如你开了家小超市,想统计「销售额」,但需要从多个角度看(比如按 “日期 商品”、“仅日期”、“仅商品”、“整体总销售额”)。假设你的销售数据长这样(简化版&#xff09…

C语言第五课:if、else 、if else if else 控制语句

C语言第五课&#xff1a;if、else 、if else if else 控制语句if else 、if else if else 联合使用编程快速学习平台if else 、if else if else 联合使用 代码示列 #include <stdio.h> int main(){//设置中文编码输出到控制台system("chcp 65001");//今天星…

七彩喜智慧养老:用科技温暖晚年,让关爱永不掉线

“当银发潮遇见科技力&#xff0c;养老方式正在发生一场静悄悄的变革。”你有没有想过&#xff1a;当父母年迈独居时&#xff0c;如何确保他们的安全&#xff1f;当老人突然摔倒&#xff0c;如何第一时间获得救助&#xff1f;当慢性病需要长期管理&#xff0c;如何避免频繁奔波…

window显示驱动开发—为头装载和专用监视器生成自定义合成器应用(二)

显示相关的 API 的比较 API用途和目标受众DisplayInformation用于检索 CoreWindow 的呈现和布局属性。HdmiDisplayInformation用于枚举和设置受限模式集的仅限 Xbox 的 API。 高度专用于 Xbox 媒体应用方案。DisplayMonitor用于查询物理监视器设备的属性。 不公开有关操作系统…

Linux 高性能 I/O 事件通知机制的核心系统调用—— `epoll_ctl`

epoll 是 Linux 上处理大量文件描述符 I/O 事件的高效模型&#xff0c;而 epoll_ctl 则是你用来指挥 epoll 实例&#xff08;epoll instance&#xff09;的“遥控器”&#xff0c;负责向它添加、修改或删除需要监视的文件描述符&#xff08;FD&#xff09;及其感兴趣的事件。1.…

mysql 必须在逗号分隔字符串和JSON字段之间二选一,怎么选

如果必须在逗号分隔字符串和JSON字段之间二选一&#xff0c;那么 JSON字段是明显更好的选择。以下是详细的对比分析&#xff1a;对比结论&#xff08;直接看这里&#xff09;方面JSON字段逗号分隔字符串胜出方查询能力✅ 丰富的JSON函数支持❌ 只能使用LIKE模糊查询JSON数据验证…

DPI和DIP的区别

DPI 和 DIP 是两个在计算机图形和移动开发领域常见的术语&#xff0c;它们都与屏幕显示和尺寸有关&#xff0c;但含义和用途不同。 DPI (Dots Per Inch) 定义&#xff1a;DPI 的全称是 Dots Per Inch&#xff0c;即每英寸点数。它是一个衡量物理密度的单位&#xff0c;表示在…

数据帮助我们理解未知世界

主持人 尼古拉安根&#xff1a; 大家好&#xff0c;我是挪威南方财富基金首席执行官尼古拉安根。今天非常荣幸能与大卫斯皮格尔哈尔特爵士对话。坦率地说&#xff0c;他不仅是世界上最优秀的统计学家之一&#xff0c;也是我见过的最佳风险沟通者。他撰写了大量优秀著作&#xf…

在使用git的很多操作是保持工作区干净

这是一条铁律下面是错误操作&#xff1a;自己明明写完了代码&#xff0c;想要提交。此时你的工作区长这样你的提交顺序是&#xff1a;git pull -> git commit -> git push但是现实往往不这样&#xff0c;万一拉下来的代码和你当前工作区的代码有冲突&#xff0c;你必须要…

通过语法推导树快速求短语,简单短语和句柄

第一步&#xff1a;写出规范推导&#xff08;最右&#xff09;序列 规范推导就是最右推导。我们的目标是从起始符号 E 出发&#xff0c;通过每步替换最右边的非终结符&#xff0c;最终得到句型 R(Pi)。 文法 G[E]: E :: RP | PP :: (E) | iR :: RP | RP* | P | P* 推导过程&…

智能学习辅助系统-部门管理开发

文章目录准备工作工程搭建增删改查查询部门删除部门新增部门修改部门查询回显修改数据日志技术准备工作 需求&#xff1a;部门管理的查询、新增、修改、删除 使用REST风格的URL&#xff1a; GET &#xff1a; 查询POST &#xff1a;新增PUT &#xff1a; 修改DELETE &#x…

【图解】idea中快速查找maven冲突

现象 今天启动项目时&#xff0c;总是以下报错&#xff0c;并退出SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/F:/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.13.3/log4j-slf4j-impl-2.13.3.jar!/org/slf4j/im…

LightGBM、XGBoost和CatBoost自定义损失函数和评估指标

LightGBM、XGBoost和CatBoost自定义损失函数和评估指标函数&#xff08;缩放误差&#xff09;数学原理损失函数定义梯度计算评估指标LightGBM实现自定义损失函数自定义评估指标使用方式XGBoost实现自定义损失函数自定义评估指标使用方式CatBoost实现自定义损失函数自定义评估指…