做web开发我们经常会做代码走查很多时候我们都会抽查一些核心功能或者常会出现漏洞的逻辑随着技术团队的壮大组员技术日益成熟 常见傻瓜型SQL注入漏洞以及XSS漏洞会越来越少但是我们也会发现一些新兴的隐蔽性漏洞偶尔会出现这些漏洞更多来自开发人员对一个函数常见 模块功能设计不足遗留下的问题以前我们能够完成一些功能模块现在要求是要安全正确方法完成模块才行 接下来我会分享一些常见功能模块由于设计原因导致漏洞出现下面我们先看下读取文件型功能漏洞
我们先看下下面一段代码通过用户输入不同目录包含不同文件
<?php///读取模块名称$mod = isset($_GET[m])?trim($_GET[m]):index;///过滤目录名称不让跳转到上级目录$mod = str_replace(""""$mod);///得到文件$file = "/home/www/blog/"$mod"php";///包含文件@include($file);
这段代码可能在很多朋友做的程序里面有遇到过对于新人来说也是很容易出现这样问题记得走查遇到该代码时候我问到你这个代码安全方面能做到那些?
答 对””目录有做替换因此用户传入模块名里面有有目录都会被替换掉了
构造拼接file名称有前面目录限制有后面扩展名限制包含文件就会限制在该目录了
我们来测试下如果$mod传入这个值将会是什么样的结果
$mod 通过构造输?mod=…%F…%F…%F…%Fetc%Fpasswd% 我们看结果将是
居然include(“/etc/passwd”)文件了
首先做参数过滤类型去限制用户输入本来就不是一个好方法一般规则是能够做检测的不要做替换只要是检测不通过的直接pass 掉!这是我们的一个原则过滤失败情况举不胜举我们来看看实际过程
输入”…/…/…/” 通过把”” 替换为””后
结果是”///” 就变成了这个了
有朋友就会说如果我直接替换为空格是不是就好了?在这个里面确实可以替换掉但是不代表以后你都替换为空格就好了再举例子下如有人将字符串里面javascript替换掉代码如下
……
$msg = str_replace(“javascript”””$msg);
看似不会出现了javascript了但是如果输入:jjavascriptavascript 替换会替换掉中间一个变为空后前面的”j” 跟后面的会组成一个新的javascript了
其次我们看看怎么逃脱了后面的php 限制呢用户输入的参数有”etc/passwd” 字符非常特殊一段连接后文件名称变成了”……etc/passwdphp”你打印出该变量时候还是正确的但是一段放入到文件读写 操作方法里面后面会自动截断操作系统只会读取……etc/passwd文件了 “”会出现在所有文件系统读写文件变量中都会同样处理这根c语言作为字符串完整标记有关系
通过上面分析大家发现做文件类型操作时候一不注意将产生大的漏洞而且该漏洞就可能引发一系列安全问题
到这里估计有人就会思考这个做文件读写操作时候如果路径里面有变量时候我该怎么样做呢?有人会说替换可以吗? “可以”但是这个方法替换不严格将会出现很多问题而且对于初写朋友也很难杜绝 做正确的事情选择了正确的方法会从本身杜绝问题出现可能了 这里我建议对于变量做白名单限制
- 什么是白名单限制
举例来说
$mod = isset($_GET[m])?trim($_GET[m]):’index’;///读取模块名称后
mod变量值范围如果是枚举类型那么
if(!in_array($modarray(‘user’’index’’add’’edit’))) exit(‘err!!!’);
完全限定了$mod只能在这个数组中够狠!!!!
- 怎么做白名单限制
通过刚才例子我们知道如果是枚举类型直接将值放到list中即可但是有些时候这样不够方面我们还有另外一个白名单限制方法就是限制字符范围
举例来说
$mod = isset($_GET[m])?trim($_GET[m]):’index’;///读取模块名称后
我限制知道$mod是个目录名称对于一般站点来说就是字母加数字下划线之类
if(!preg_match(“/^w+$/”$mod)) exit(‘err!!!’);
字符只能是[AZaz_] 这些了够狠!!!
总结是不是发现白名单限制方法做起来其实很简单你知道那个地方要什么就对输入检测必须是那些而且检测自己已知的比替换那些未知的字符是不是简单多了 好了先到这里正确的解决问题方法会让文件简单而且更安全!!欢迎交流!