说说PHP中的SQL注入

最近在工作中遇到一个 SQL 注入,虽然影响不是很大,但也足够让我静下来思考,SQL 注入问题好像很简单、好像每个人都明白,但在实际的开发中还是会出现这样低级的错误,出现这样的问题个人觉得和 PHP 开发随意化有关,第二个原因可能是没有明白 SQL 注入的原理。

什么是 SQL 注入

在应用程序中,为了和用户交互,允许用户输入数据,假如开发者不慎重出现漏洞,攻击者输入一些特殊的字符从而让应用程序执行了危险的 SQL 操作。危险可大可小,小的泄漏了机密数据(比如用户信息),大的危害可能会删除整个数据库。

SQL 注入根本的原因就在于被攻击者构建了危险的 SQL,看 PHP 中的一个例子:

$sql = "select * from tb where name='" . $name . "'";
mysql_query($sql);

这时候假如 $name 的值被恶意输入 1' OR '1'='1,则最后的 SQL 就是select * from tb where name='1' OR '1'='1',从而查询出了所有的表数据,这就是比较简单的 SQL 注入。

构建危险 SQL 的主要原因在于 SQL 语句中的“双引号”、“单引号”、“关键字”。利用这些字符攻击者可以构建出很多其他语义的 SQL。

如何避免 SQL 注入

上面说到 SQL 注入的原因在于“双引号”、“单引号”、“关键字”,所以预防的方法就在于“破坏”这些特殊字符。主要有两种方法:

(1)过滤数据

在开发程序的时候,根据应用的限制,应该明确规定用户输入的数据是什么类型的,比如是字符串,还是整型,或者是富文本数据,应用程序就必须严格的限制,比如某些输入假如过滤了“单引号”等特殊符号,自然就构建不起危险的 SQL 了。

为什么在 PHP 语言中会出现很多的低级操作呢?有部分原因就在于 PHP 太灵活了,比如在数据层直接使用$_GET变量的值构建 SQL,从而导致问题。当然这不完全是语言的问题,主要在于语言结构太灵活,开发者肆无忌惮导致的。

(2)转义数据

由于“双引号”、“单引号”等特殊字符在 SQL 语句中有特殊的能力(指令),所以用户输入的这些特殊符号在构建 SQL 的时候就也有了特殊的含义,假如我们通过一种方式让用户输入的特殊符号没有其特殊能力(只有字符本身的含义),那么就不会出现 SQL 注入了,这种方式就是转义,在 MySql 中内置了这样的函数 mysql_real_escape_string()

SQL 中 select/update/delete/insert 语句都需要转义,对于 insert 语句来说,转义不代表插入的数据在表中多了个反斜杠字符,这个概念一定要清楚,在数据库存储里面是不会放入反斜杠转义符号的。

接下来重点看看如何在 PHP 中进行转义数据。

mysql(mysqli) 扩展库

PHP 语言是从 C 语言发展而来的,所以早期其实很多函数和 C 语言函数同名,这也说明大部分 PHP 函数的实现就是调用 C 语言函数库。MySql 扩展就是典型的一个函数库(调用本地的 C 命令函数库)。

PHP 中的 mysql_real_escape_string() 函数就是执行转义的,只要在输入的数据变量上调用这个函数,就能解决大部分注入问题。

这个函数很简单,这里说说一个很古老的函数 addslashes(),在我早期使用 PHP 过程中,经常遇到这个函数,它也能对字符串进行转义,所以很多人用它代替 mysql_real_escape_string() 函数,其实这是不对的一种方法,因为两者转义的具体字符是不一样的,同时 addslashes() 不并是专门用户转义数据库中的字符。

抛开数据库操作来说,在如今的 PHP 中也不建议使用 addslashes() 函数,在 PHP 早期版本中,$_GET$_POST 数据会自动进行 addslashes() 调用(猜测是为了保证数据的安全),可也破坏了一个规则——不应该修改用户的原始数据,所以在新版本 PHP 中,这个函数对应的 magic_quotes_gpc 指令是关闭的,但是从我的角度来看,PHP 开发者应该尽量去忘记这个函数的存在。

PDO

如何理解 PDO 呢?可以看看 mysqli 包的一些弱点:

  • PHP 开发者可能会操作 MySql 或者其他类型的数据库,但是 mysqli 库只能操作 MySql,对于 PHP 开发者来说没有统一的接口去操作 SQL 语言(注意不是操作数据库)。
  • mysqli 上的一些 SQL 操作功能缺乏,比如没有事务处理等等。

而 PDO 就能解决上述两个问题,而具体到转义操作上,PDO 通过Prepared Queries让你来构建更安全的 SQL 语句,对于 mysql_real_escape_string() 来说开发者还是需要自己构建 SQL 语句,而 PDO 可以提供更优雅的方式操作 SQL。

$stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name");
$stmt->execute(array(':name' => $name, ':id' => $id));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

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

推荐阅读更多精彩内容

  • Php:脚本语言,网站建设,服务器端运行 PHP定义:一种服务器端的HTML脚本/编程语言,是一种简单的、面向对象...
    廖马儿阅读 2,114评论 2 38
  • Welcome 目前网络上充斥着大量的陈旧信息,让PHP新手误入歧途,传播着错误的实践和糟糕的代码,这必须得到纠正...
    layjoy阅读 21,655评论 7 118
  • Composer Repositories Composer源 Firegento - Magento模块Comp...
    零一间阅读 3,956评论 1 66
  • Web安全简史 在Web1.0时代,人们更多是关注服务器端动态脚本语言的安全问题,比如将一个可执行脚本(俗称Web...
    潘良虎阅读 3,918评论 3 72
  • 产品想畅销须知工业设计的五大元素 好设计不等于好产品,好产品一般都能够通过市场的考研,赢得市场获得客户的认可。工业...
    优概念设计阅读 794评论 0 4