你有一份SQL注入漏洞安全邮件请查收

天有不测风云,事情的起因要从这次突然的内网接口安全扫描说起。这天小马突然收到大大转发的邮件,被告知某几个api存在SQL注入风险,需要立刻处理。原本安全部门是不对内网的api扫描的,可能是因为作为cgi,已经处于中间过程了,所以默认安全不扫描,自然而然程序员们也就不关注这块参数的过滤。好吧,这次人家开启内网扫描自然也是无可厚非的。于是小马排查代码后,发现大多参数都是整形参数导致的,于是用了比较简单的方式解决了,就是对参数进行整形强制类型转换。重新测试扫描,没有报注入问题了。

其实SQL注入的原理很简单,就是引号捣的鬼。这个小马在很早之前有篇文章《我不会盗QQ》,阐述得比较详细了,这里不赘述。那么写PHP该怎么防止SQL注入呢?小马整理了下,供参考。

1、关于魔术引号是否开启

在PHP.ini中设置:magic_quotes_gpc = ON。

如果设置了这个选项,那么php解析器就会自动为POST、GET、COOKIE过来的数据中所有的 '(单引号)、"(双号号)、\(反斜线)、空白字符,都为在前面自动加上转义字符"\"。

magic_quotes_gpc = Off是 php 中一种非常不安全的选项。新版本的 php 已经将默认的值改为了 On,但仍有相当多的服务器的选项为 off。有趣的是,在php5.4的更高版本中,这个选项被去掉了,即是php解析器不会自动为POST、GET、COOKIE过来的数据增加转义字符"\",而是把安全编码交给了用户自己,从而避免了magic_quotes_gpc未设置,用户依赖这个设置而带来了安全隐患。从小马的经验来看,如果默认 On对一些参数接收后的原始参数校验会有些干扰,因为毕竟有可能在原传参的基础上多了\反斜杠。

我们可以用get_magic_quotes_gpc()函数来识别当前的magic_quotes_gpc配置是否为ON,根据结果再进一步处理参数。

对这些符号,特别是引号加转义反斜杆的目的还是为了在SQL语句执行的时候,外部传参的引号(字符串)不被SQL解析成SQL的语法引号。举个例子如下:

不对单引号转义直接拼接SQL(加粗部分为外部传参):

ELECT * FROM tbl_users  WHERE username='zhang3 '  OR 1 =1 UNION select cola, colb,cold FROM tbl_b #' AND password = 'abc123' LIMIT 0,1

单引号转义后拼接SQL,无法达到注入的目的:

SELECT * FROM tbl_users WHERE username='zhang3\' OR 1=1 #' AND password = 'abc123'  LIMIT 0,1

总结:我们只要保持到SQL语句的变量是转义处理过的就可以了。或者说能保证经过参数校验过滤剔除强转后再拼接到SQL语句的也行,不能让参数传来的引号赤裸裸在SQL语句中。

因此,对入参万能的转义公式(不管环境中魔术引号是否开启),通常如下:

if (!get_magic_quotes_gpc())

{

if (!empty($_GET))

{

$_GET = addslashes_deep($_GET);//封装addslashes函数支持对数组参数进行递归转义。反转义函数:$str=stripcslashes($str)

}

if (!empty($_POST))

{

$_POST = addslashes_deep($_POST);

}

$_COOKIE = addslashes_deep($_COOKIE);

$_REQUEST = addslashes_deep($_REQUEST);

}

但这个万能方式有一个弊端,就是上面说的,等效于magic_quotes_gpc = ON,反斜杠会对原始传参有污染,请根据实际项目逻辑酌情添加。

2、在第一步也可以对参数进行过滤(这是适合放在入参转义的前面做的)

第一步先过传参中的滤特殊字符(如DB关键字,脚本标签,int化类型校验等),这个在阿里云对注入的处理建议中就有体现,对方直接提供了一个危险参数匹配过滤的文件,只要接进去过滤传参就可以了,不过小马见过这个过滤的代码比较长,因为匹配比较多,性能要考虑。

3、还可以用上一些DB底层的过滤转义函数,比如mysqli_real_escape_string转义特殊字符,但要注意是否存在重复转义的问题(比如已经 addslashes了就别再mysqli_real_escape_string了)。特别注意: 如果是转义符号,MySQL执行的时候会自动吃掉 比如\\\'入库是\'; \\' 入库是 \'; \'入库是'。

如果我们因为业务逻辑原因不用用上面提到的入参万能转义函数,那么就可以选择在DB底层来转义。在进行sql语句执行前,必须转义任何变量:

mysql_real_escape_string — 转义 SQL 语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集。但本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLi 或 PDO_MySQL 扩展 配合过滤器来替换。

4、最后入库的时候能对语句预处理就预处理,如MySQLi 和PDO(加额外的一层防止,但不能仅仅只靠预处理这一层,会有分险,别问我怎么知道的)

因为单单底层的预处理 解决不了SQL注入问题,这次的告警就是个铁证。原理大概是这样。文中说:预处理语句能很好的防止 sql注入,因为参数的发送不会影响一开始对模板的解析,编译,模版又是自己定义的,根本不会有漏洞。

如果说预处理会把注入的变量' AND 1=1 自动当一个值处理 而不会拼接成SQL语句语法,如果是这样那就对防止SQL注入有效,但为什么本次扫描还报注入漏洞呢,小马排查底层代码是有预处理的(本来也是想着依赖这一层,没想到没防住)?个人反而感觉预处理只是 对?问号的值替换,该拼接的还是会拼接,没啥防注入效果,这点需特别小心和关注。只至小马看了以上的这篇文章后,方知此预处理非彼预处理,特来更正。文章中的才是真正的预处理语法,从代码中,我们就可以看到预处理语句的两大优势的体现。首先是占位符,使用占位符之后,我们就不用在 SQL 语句中去写单引号,单引号往往就是 SQL 注入的主要漏洞来源。bindParam() 方法会自动地转换绑定数据的类型。当然,bindParam() 方法也可以在可选的参数中指定绑定的数据类型,这样就能让我们的代码更加安全了,大家可以查阅相关的文档。而小马使用的预处理只是底层的预处理语法并没有按预处理的语法处理传参SQL语句中的参数还是拼接的,只是用了sprintf替换而已,所以是无效的,并不代表预处理本身无法防止SQL注入。

另一个优势就是模板的能力,我们只定义了一个 PDOStatement 对象,然后通过改变数据的内容,就可以多次地使用 execute() 方法去执行预处理语句。

总结:建议处理流程,特殊字符过滤剔除;参数校验类型转换;入库之前使用转义addslashes函数;底层预处理;SQL执行。

其他环境上的诸如,PHP配置文件中Register_globals=off; php安全模式:safe_mode=on等等环境配置上的安全策略也需要关注。

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

推荐阅读更多精彩内容