本篇文章给大家带来的内容是关于如何防范用户上传PHP可执行文件,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
每个专业的 PHP 开发者都知道用户上传的文件都是极其危险的。不论是后端和前端的黑客都可以利用它们搞事情。
大约在一个月前,我在 reddit 上看了一篇 PHP 上传漏洞检测 ,因此, 我决定写一篇文章。用户 darpernter 问了一个棘手的问题:
尽管我将其重命名为 'helloworld.txt', 攻击者是否仍然能够运行他的php 脚本?
置顶的答复是:
如果文件后缀修改为 .txt ,那么它不会被当做php文件执行,这样你安心了吧,不过再三确保不是 .php.txt 的后缀上传。
不好意思,问题的正确答案并非如此 . 虽然上面的答复并非全部错误,但显然不全面。让人惊讶的是,大多数的答案都非常相似。
我想解释清楚这个问题。所以我要讨论的东西变得有点大,我决定让它变得更大。
问题
人们允许用户上传文件,但是担心用户上传的文件在服务器上被执行。
从 php 文件如何被执行开始看。假设一个有 php 环境的服务器,那么它通常有两种方法在外部执行 php 文件。一是直接用 本文来源gao.dai.ma.com搞@代*码#网搞代gaodaima码URL 请求文件,像 http://example.com/somefile.php 。第二种是 php 现在常用的,将所有请求转发到 index.php ,并在这个文件中以某种方式引入其他文件。所以,从 php 文件中运行代码有两种方式:执行文件或用 include/include_once/require/require_once 的方法引入其他需要运行的文件。
其实还有第三种方法:eval() 函数。它能将传入的字符串当做 php 代码执行。这个函数在大多数 CMS 系统中被用来执行存储在数据库里的代码。eval() 函数非常危险,但如果你用了它,通常就意味着你确认自己在做危险的操作,并确认你已经没有其他选择。实际上, eval() 有它的用途,并且在某些情况下非常有用。但如果你是新手的话,我不推荐你使用它。请看 这篇在 OWASP 的文章。我在上面写了很多。
所以,有两种方法执行文件里的代码:直接执行或者在被执行的文件中引入它。那么如何避免这种事情发生呢?
解决方法?
我们怎样才能知道一个文件包含 php 代码呢?看拓展名,如果以 .php
结尾的,像 somefile.php
我们就认为它里面有 php 代码。
如果在网站根目录下有一个 somefile.php
文件,那么在浏览器访问 http://example.com/somefile.php
,这个文件就会被执行并且输出内容到浏览器上。
但是如果我重命名这个文件会怎样?如果我把它重命名为 somefile.txt
或者是 somefile.jpg
呢?我会得到什么?我会得到它的内容。它不会被执行。它会从硬盘(或者缓存)直接被发送过来。
在这点上 reddit 社区上的答案是对的。重命名能防止一个文件被非预期的执行,那么为什么我认为这种解决方法是错的呢?
我相信你注意到我在 “解决方法” 后面加的问号。这个问号是有意义的。现在大多数网站的 URL 上几乎看不到单独的 php 文件。并且就算有,也是人为故意伪造的,因为 URL 上需要有 .php
来实现对老版本 URL 的向后兼容。
现在绝大部分 php 代码是在运行中被引入的,因为所有请求都被发送到了网站根目录的 index.php
。这个文件会根据特定的规则引入其他 php 文件。这种规则可能(或者在将来会)被恶意使用。如果你应用的规则允许引入用户的文件,那么应用会容易遭到攻击,你应该立即采取措施防止用户的文件被执行。