PHP Manual
/
安全问题

在PHP和文件附件中包含安全性

22. 08. 2019

Obsah článku

通常情况下,我们可能想在一个页面上附加一个文件,而这个文件已经存储在其他地方的磁盘上。如果我们直接在attach函数中输入它的确切名称,就没有什么可担心的。

安全地附加一个文件

include 'menu.html';

前面的写法是完全安全的,因为我们总是挂载同一个文件。在这种情况下不能发生安全错误。唯一可能发生的问题是没有menu.html文件,这将触发一条警告信息(反正可能不会出现),但这种情况很少,因为我们通常会附上一个几乎确定存在的文件。

根据模式附加一个文件

但是,如果,比如说,我们想把文章附在像这样的简单内容网站上呢?在这个网站上,我有一个物理文件夹,里面存放着HTML格式的文章,我直接把它们附在源代码中。

然而,仅仅是连接是不够的!我们需要的是更多的时间。初学者可以这样调用个别文章。

include '文章/' . $_GET['文章'] . '.html';

但这是非常危险的。攻击者可以用.../或类似的东西作为文章名称传递到另一个目录的链接,有时可以通过在结尾传递一个空字节来摆脱结尾。你至少应该使用basename()函数,但最好只允许白名单的值。

为什么不加载不相关的文件?

通常情况下,我们不介意加载一个不正确的(意外的)文件--这是用户的错,因为他们请求了一个他们实际上不想要的页面,但可能有一些情况下,这确实很重要。特别是。

  • 用户加载一个公众无法访问的文件,只有服务器可以得到它。
  • 加载其他一些PHP脚本可能会触发一个意外的动作或错误信息,这可能会给网站的工作方式带来提示,有助于进一步的攻击。
  • 加载另一个文件不仅可能导致它被添加到文件中,而且还可能导致它运行。

白名单和输入验证

如果我们没有能力以某种安全的方式验证输入(例如从白名单中),我们就不应该依赖用户的诚实,反正至少在PHP层面上要为脚本辩护。

第一件重要的事是把所有加载的文件放在同一个文件夹(目录)中,并禁用一些危险的字符,特别是斜线和点。这将使人们无法访问含有潜在漏洞文件的其他文件夹。禁用危险字符也可以通过简单地从输入字符串中删除它们来实现。

$load = '.../index'; // 这个输入可能有潜在的危险
$load = strtr($load, './', ''); // 删除字符串中的所有点和斜线
include $load .'.html';

运行文件?

需要注意的是,include结构在连接时执行文件的方式与PHP代码相同,所以允许这种可能性是个好主意。

然而,通常情况下,我们会附加一些不需要事后执行的文件,而且我们只对字符串形式的存储文本(内容)感兴趣。因此,我们可以将文件加载到一个变量中,并将其作为一个字符串来处理,这是很安全的。

$load = '.../index'; // 这个输入可能有潜在的危险
$load = strtr($load, './', ''); // 删除字符串中的所有点和斜线
$file = file_get_contents($load . '.html'); // 将内容加载到变量中
echo $file; //转储文件的内容

这个解决方案乍看起来很有趣,也很安全--而且它确实很安全。即使用户设法调用了一个 PHP 文件,它也不会运行。然而,它可能会显示它(指它的源代码),我们需要对此加以注意。

从脚本中识别出所需的文件

这方面没有明确的指南,每个人都必须根据剧本的需要自己去做。例如,我从其他文件中识别出一篇文章,因为它们包含一个大小为H1的标题。 因此,如果有人加载一个没有标题的文件,我不会显示任何东西,页面以错误信息结束。找到一些只有你想要的文件才有而其他文件没有的独特功能总是很重要的,你可以从这里开始。

总结

虽然验证和加载文件相对简单,但大量的初学者仍然会犯错--而且会继续犯错。最重要的是要正确理解我们所装载的内容的含义,以及如何将我们想要的内容与其他内容区分开来。最重要的是,要把内容作为一个字符串来处理,千万不要把它直接加载到页面中。

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
Status:
All systems normal.
2024