SQL注入会引发什么问题?
SQL注入是一种对数据库的恶意攻击,注入进去的恶意指令就会被误认为是正常的SQL指令而执行,因此遭到破坏或是入侵。
什么是SQL注入?
SQL注入(英语:SQL injection),也称SQL注入或SQL注码,是发生于应用程序与数据库层的安全漏洞。简而言之,是在输入的字符串之中注入SQL指令,在设计不良的程序当中忽略了字符检查,那么这些注入进去的恶意指令就会被数据库服务器误认为是正常的SQL指令而执行,因此遭到破坏或是入侵。
为什么会发生SQL注入?
在设计不良的应用程序中,对用户输入数据的合法性并没有判断或过滤不严导致。
如图中所示,没有对客户端用户输入的数据合法性进行检查或过滤,导致客户端用户可以任意构造自己想要的参数,达成SQL注入条件,最终引发严重的后果,如果在账号登录成功SQL注入,那么就可以成功登录他人的账号,使用对他人的账号进行一系列破环手段,比如黑客通过SQL注入成功登录你的微信,可以使用你微信里面的余额,给你的家人朋友发钓鱼链接等等。
-
资料表中的资料外泄,例如企业及个人机密资料,账户资料,密码等。
-
数据结构被黑客探知,得以做进一步攻击(例如SELECT * FROM sys.tables)。
-
数据库服务器被攻击,系统管理员账户被窜改(例如ALTER LOGIN sa WITH PASSWORD=’xxxxxx’).
-
获取系统较高权限后,有可能得以在网页加入恶意链接、恶意代码以及Phishing等。
-
经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统(例如
xp_cmdshell “net stop iisadmin”可停止服务器的IIS服务)。
-
攻击者利用数据库提供的各种功能操纵文件系统,写入Webshell,最终导致攻击者攻陷系统
-
破坏硬盘资料,瘫痪全系统(例如xp_cmdshell “FORMAT C:”)。
-
获取系统最高权限后,可针对企业内部的任一管理系统做大规模破坏,甚至让其企业倒闭。
网站主页被窜改,导致声誉受到损害。
-
总之作为程序设计者,需要保证程序的健壮性避免被SQL注入攻击。
如何避免SQL注入?
- 所有的查询语句都使用数据库提供的参数化查询(Parameterized Query)接口,参数化的语句使用参数而不是将用户输入变量嵌入到 SQL语句中,当前几乎所有的数据库系统都提供了参数化 SQL语句执行接口,使用此接口可以非常有效的防止 SQL注入攻击。
set @name := xxx; set @pwd := xxx; select id from users where name = @name and pwd = @pwd
- 在组合SQL字符串时,先针对所传入的参数加入其他字符(对进入数据库的特殊字符('<>&*;等)进行转义处理)。
- 确认每种数据的类型,比如数字型的数据就必须是数字,数据库中的存储字段必须对应为int型。
try: pwd = int(param.get("pwd")) except (TypeError, ValueError): return "pwd type must be int"
-
数据长度应该严格规定,能在一定程度上防止比较长的SQL注入语句无法正确执行。
name_max_length = 12 if len(param.get("name", "")) > name_max_length: return "name length cannot be greater than 12"
- 网站每个数据层的编码统一,建议全部使用 UTF-8编码,上下层编码不一致有可能导致一些过滤模型被绕过。
- 严格限制网站用户的数据库的操作权限,给此用户提供仅仅能够满足其工作的权限,从而最大限度的减少注入攻击对数据库的危害
- 避免网站显示 SQL错误信息,比如类型错误、字段不匹配等,防止攻击者利用这些错误信息进行一些判断。
案例
这里分析一个案例
1.数据库中先创建用户表及数据
-- 创建一张用户表
CREATE TABLE `users` (
`id` INT(11) NOT NULL AUTO INCREMENT,
`username` VARCHAR(20),
`password` VARCHAR(50),
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 插入数据
INSERT INTO users(username,`password`) VALUES('张三','456123'),('李
四','qqatfv'),('王五','Qwe123');
INSERT INTO users(username,`password`) VALUES('小张','987456'),('小
王','ngjplg'),('小李','!@#$%^');
-- 查看数据
SELECT * FROM users;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | 张三 | 456123 |
| 2 | 李四 | qqatfv |
| 3 | 王五 | Qwe123 |
| 4 | 小张 | 987456 |
| 5 | 小王 | ngjplg |
| 6 | 小李 | !@#$%^ |
+----+----------+----------+
6 rows in set (0.00 sec)
2.编写一个登录程序
import pymysql
def login():
# 打开数据库连接
db = pymysql.connect(host='127.0.0.1', port=3306, user='root',
passwd='12345', db='test', charset='utf8')
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()
username = input('请输入用户名:')
password = input('请输入密码:')
sql = "select * from users where username = '%s' and password =
'%s'" % (username, password)
print(sql)
# 执行SQL语句
cursor.execute(sql)
results = cursor.fetchone()
if results:
print('登录成功')
else:
print('登录失败')
# 关闭数据库连接
db.close()
2.1.正常登录
>>> login()
请输入用户名:>? 张三
请输入密码:>? 456123
select * from users where username = '张三' and password = '456123'
登录成功, 你好:张三
2.2.登录失败
>>> login()
请输入用户名:>? 张三
请输入密码:>? 123456
select * from users where username = '张三' and password = '123456'
用户名或密码错误,请重新输入
2.3.模拟注入
or '1' = '1'
的条件,此时不管密码是否正确都可以成功登录login()
请输入用户名:>? 张三
请输入密码:>? 123456' or '1' = '1
select * from users where username = '张三' and password = '123456' or
'1' = '1'
登录成功, 你好:张三
3.解决方法,采用参数化查询
import pymysql
def login():
# 打开数据库连接
db = pymysql.connect(host='127.0.0.1', port=3306, user='root',
passwd='12345', db='test', charset='utf8')
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()
username = input('请输入用户名:')
password = input('请输入密码:')
sql = "select * from users where username = %s and password = %s"
# 执行SQL语句
cursor.execute(sql, (username, password))
results = cursor.fetchone()
if results:
print('登录成功, 你好:', username)
else:
print('用户名或密码错误,请重新输入')
# 关闭数据库连接
db.close()
3.1.正常登录
>>> login()
请输入用户名:>? 张三
请输入密码:>? 456123
登录成功, 你好:张三
3.2.登录失败
>>> login()
请输入用户名:>? 张三
请输入密码:>? 123456
用户名或密码错误,请重新输入
3.3.继续模拟注入
此处我们给SQL注入了一个 or '1' = '1'
的条件,此时我们使用的是参数化查询方式有效的防止了SQL注入
login()
请输入用户名:>? 张三
请输入密码:>? 123456' or '1' = '1
用户名或密码错误,请重新输入
本网站的文章部分内容可能来源于网络,仅供大家学习与参考。如有侵权请发送邮件到a-heartbeat-away@qq.com进行删除处理。
1 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
2 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
3 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
请登录后查看评论内容