何谓SQL注入,这个漫画告诉你

先来看一副很有意思的漫画:

何谓SQL注入,这个漫画告诉你

今天我们来聊一聊SQL注入相关的内容。

何谓SQL注入?

SQL注入是一种非常常见的数据库攻击手段,SQL注入漏洞也是网络世界中最普遍的漏洞之一。大家也许都听过某某学长通过攻击学校数据库修改自己成绩的事情,这些学长们一般用的就是SQL注入方法。

SQL注入其实就是恶意用户通过在表单中填写包含SQL关键字的数据来使数据库执行非常规代码的过程。简单来说,就是数据「越俎代庖」做了代码才能干的事情。这个问题的来源是,SQL数据库的操作是通过SQL语句来执行的,而无论是执行代码还是数据项都必须写在SQL语句之中,这就导致如果我们在数据项中加入了某些SQL语句关键字(比如说SELECT、DROP等等),这些关键字就很可能在数据库写入或读取数据时得到执行。

多言无益,我们拿真实的案例来说话。下面我们先使用SQLite建立一个学生档案表。

SQL数据库操作示例

import sqlite3 

# 连接数据库 
conn = sqlite3.connect('test.db') 

# 建立新的数据表 
conn.executescript('''DROP TABLE IF EXISTS students; 
 CREATE TABLE students 
 (id INTEGER PRIMARY KEY AUTOINCREMENT, 
 name TEXT NOT NULL);''') 

# 插入学生信息 
students = ['Paul','Tom','Tracy','Lily'] 

for name in students: 
 query = "INSERT INTO students (name) VALUES ('%s')" % (name) 
 conn.executescript(query); 

# 检视已有的学生信息 
cursor = conn.execute("SELECT id, name from students") 
print('IDName') 
for row in cursor: 
 print('{0}{1}'.format(row[0], row[1])) 

conn.close() 

点击运行按钮将会打印目前表中的内容。上述程序中我们建立了一个test.db数据库以及一个students数据表,并向表中写入了四条学生信息。

那么SQL注入又是怎么一回事呢?我们尝试再插入一条恶意数据,数据内容就是漫画中的"Robert');DROP TABLE students;--",看看会发生什么情况。

SQL数据库注入示例

conn = sqlite3.connect('test.db') 

# 插入包含注入代码的信息 
name = "Robert');DROP TABLE students;--" 
query = "INSERT INTO students (name) VALUES ('%s')" % (name) 

conn.executescript(query) 

# 检视已有的学生信息 
cursor = conn.execute("SELECT id, name from students") 
print('IDName') 
for row in cursor: 
 print('{0}{1}'.format(row[0], row[1])) 

conn.close() 

你将会发现,运行后,程序没有输出任何数据内容,而是返回一条错误信息:表单students无法找到!

这是为什么呢?问题就在于我们所插入的数据项中包含SQL关键字DROP TABLE,这两个关键字的意义是从数据库中清除一个表单。而关键字之前的Robert');使得SQL执行器认为上一命令已经结束,从而使得危险指令DROP TABLE得到执行。也就是说,这段包含DROP TABLE关键字的数据项使得原有的简单的插入姓名信息的SQL语句。

"INSERT INTO students (name) VALUES ('Robert')" 

变为了同时包含另外一条清除表单命令的语句

"INSERT INTO students (name) VALUES ('Robert');DROP TABLE students;--" 

而SQL数据库执行上述操作后,students表单被清除,因而表单无法找到,所有数据项丢失。

如何防止SQL注入问题

那么,如何防止SQL注入问题呢?

大家也许都想到了,注入问题都是因为执行了数据项中的SQL关键字,那么,只要检查数据项中是否存在SQL关键字不就可以了么?的确是这样,很多数据库管理系统都是采取了这种看似『方便快捷』的过滤手法,但是这并不是一种根本上的解决办法,如果有个美国人真的就叫做『Drop Table』呢?你总不能逼人家改名字吧。

合理的防护办法有很多。首先,尽量避免使用常见的数据库名和数据库结构。在上面的案例中,如果表单名字并不是students,则注入代码将会在执行过程中报错,也就不会发生数据丢失的情况——SQL注入并不像大家想象得那么简单,它需要攻击者本身对于数据库的结构有足够的了解才能成功,因而在构建数据库时尽量使用较为复杂的结构和命名方式将会极大地减少被成功攻击的概率。

使用正则表达式等字符串过滤手段限制数据项的格式、字符数目等也是一种很好的防护措施。理论上,只要避免数据项中存在引号、分号等特殊字符就能很大程度上避免SQL注入的发生。

另外,就是使用各类程序文档所推荐的数据库操作方式来执行数据项的查询与写入操作,比如在上述的案例中,如果我们稍加修改,首先使用execute()方法来保证每次执行仅能执行一条语句,然后将数据项以参数的方式与SQL执行语句分离开来,就可以完全避免SQL注入的问题,如下所示:

SQL数据库反注入示例

conn = sqlite3.connect('test.db') 

# 以安全方式插入包含注入代码的信息 
name = "Robert');DROP TABLE students;--" 
query = "INSERT INTO students (name) VALUES (?)" 

conn.execute(query, [name]) 

# 检视已有的学生信息 
cursor = conn.execute("SELECT id, name from students") 
print('IDName') 
for row in cursor: 
 print('{0}{1}'.format(row[0], row[1])) 

conn.close() 

而对于PHP而言,则可以通过mysql_real_escape_string等方法对SQL关键字进行转义,必要时审查数据项目是否安全来防治SQL注入。当然,做好数据库的备份,同时对敏感内容进行加密永远是最重要的。某些安全性问题可能永远不会有完美的解决方案,只有我们做好最基本的防护措施,才能在发生问题的时候亡羊补牢,保证最小程度的损失。

原文链接:http://netsecurity.51cto.com/art/201911/606877.htm

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容

  • 一. Java基础部分.................................................
    wy_sure阅读 3,810评论 0 11
  • 注入攻击的分类 1.没有正确过滤转义字符 在用户的输入没有为转义字符过滤时,就会发生这种形式的注入式攻击,它会被传...
    查无此人asdasd阅读 1,611评论 0 5
  • 1. 介绍 2. MySQL中的数据类型 数字类型 :整数: tinyint、smallint、mediumint...
    时间之友阅读 1,021评论 0 1
  • [SQL注入攻击] SQL注入攻击是黑客对数据库进行攻击的常用手段之一。随着B/S模式应用开发的发展,使用这种模式...
    James黄杰阅读 2,654评论 0 30
  • 我总是不能理所当然的做一些别人觉得很理所当然的事,那样我会觉得很愧疚。如果有一天,我做这些事都像他们那样理所当...
    Alyo哟阅读 290评论 0 0