SQL注入攻击的原理以及如何防止SQL注入(简易)

发布时间 2023-12-15 11:36:41作者: 黯然。。

?SQL注入攻击的原理

SQL 注入(SQL Injection)是发生在 Web 程序中数据库层的安全漏洞,是网站存在最多也是最简单的漏洞。主要原因是程序对用户输入数据的合法性没有判断和处理,导致攻击者可以在 Web 应用程序中事先定义好的 SQL 语句中添加额外的 SQL 语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步获取到数据信息。
?1,恶意拼接查询

我们知道,SQL 语句可以查询、插入、更新和删除数据,且使用分号来分隔不同的命令。例如:

SELECT * FROM users WHERE user_id = $user_id

其中,user_id 是传入的参数,如果传入的参数值为“1234; DELETE FROM users”,那么最终的查询语句会变为:

SELECT * FROM users WHERE user_id = 1234; DELETE FROM users

如果以上语句执行,则会删除 users 表中的所有数据。
:
? 2,利用注释执行非法命令

SELECT COUNT(*) AS ‘num’ FROM game_score WHERE game_id=24411 AND version=$version

如果 version 包含了恶意的字符串’-1’ OR 3 AND SLEEP(500)–,那么最终查询语句会变为:

SELECT COUNT(*) AS ‘num’ FROM game_score WHERE game_id=24411 AND version=‘-1’ OR 3 AND SLEEP(500)–

以上恶意查询只是想耗尽系统资源,SLEEP(500) 将导致 SQL 语句一直运行。如果其中添加了修改、删除数据的恶意指令,那么将会造成更大的破坏
:
?3,传入非法参数

SQL 语句中传入的字符串参数是用单引号引起来的,如果字符串本身包含单引号而没有被处理,那么可能会篡改原本 SQL 语句的作用。 例如:

SELECT * FROM user_name WHERE user_name = $user_name

1

如果 user_name 传入参数值为 G’chen,那么最终的查询语句会变为:

SELECT * FROM user_name WHERE user_name =‘G’chen’

1

一般情况下,以上语句会执行出错,这样的语句风险比较小。虽然没有语法错误,但可能会恶意产生 SQL 语句,并且以一种你不期望的方式运行
:
? 4,添加额外条件

在 SQL 语句中添加一些额外条件,以此来改变执行行为。条件一般为真值表达式。例如:

UPDATE users SET userpass=' u s e r p a s s ′ W H E R E u s e r i d = userpass' WHERE user_id= userpass′WHEREuseri​d=user_id;

1

如果 user_id 被传入恶意的字符串“1234 OR TRUE”,那么最终的 SQL 语句会变为:

UPDATE users SET userpass= ‘123456’ WHERE user_id=1234 OR TRUE;

1

这将更改所有用户的密码。

:

:
简而言之,SQL 注入就是在用户输入的字符串中加入 SQL 语句,如果在设计不良的程序中忽略了检查,那么这些注入进去的 SQL 语句就会被数据库服务器误认为是正常的 SQL 语句而运行,攻击者就可以执行计划外的命令或访问未被授权的数据。
:
? SQL注入的危害及案例

使得系统业务功能异常或者失效
恶意的破坏,比如修改数据,删数据,删表等恶意破坏;
探查数据库类型,结构,获取数据库敏感数据,造成数据泄露;
修改数据库配置,控制服务器,进行恶意活动等
案列
2011年6月,LulzSec的黑客组织攻击了索尼公司网站,并获取了100万用户的个人信息,包括用户名,密码,家庭住址,生日等一些敏感信息。造成了很大的影响。LulzSec组织声称入侵手段就是简单的SQL注入技术,通过SQL注入,就获取到了全部的敏感信息。

? 如何防止sql注入

? 1,采用预编译技术

INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)

使用预编译的SQL语句,SQL语句的语义不会是不会发生改变的。预编译语句在创建的时候就已经将指定的SQL语句发送给了DBMS,完成了解析,检查,编译等工作,所以攻击者无法改变SQL语句的结构,只是把值赋给?,然后将?这个变量传给SQL语句。当然还有一些通过预编译绕过某些安全防护的操作,大家感兴趣可以去搜索一下
:
?2,严格控制数据类型

在java、c等强类型语言中一般是不存在数字型注入的,因为在接受到用户输入id时,代码一般会做一个int id 的数据类型转换,假如我们输入的是字符串的话,那么这种情况下,程序就会报错。但是在PHP、ASP这些没有强调处理数据类型的语言,一般我们看到的接收id的代码都是如下等代码。

$id = $_GET[‘id’];
$SQL = “select * from ‘某字段’ where id = $id;”;

这样的代码攻击者就可以通过构造id参数运用联合查询等手法进行SQL注入,假如这里我们加入一个检查数字类型函数is_numeric()这样就可以防止数字型注入了
:
?3,对特殊的字符进行转义

数字型注入可以通过检查数据类型防止,但是字符型不可以,那么怎么办呢,最好的办法就是对特殊的字符进行转义了。比如在MySQL中我们可以对" ’ "进行转义,这样就防止了一些恶意攻击者来闭合语句。当然我们也可以通过一些安全函数来转义特殊字符。如addslashes()等,但是这些函数并非一劳永逸,攻击者还可以通过一些特殊的方式绕过