在PHP中真的需要"不直接加载此页面"吗?
我本来想问做这件事的最好方法是什么,但是后来决定应该问这是否是必要的。我从未在JSP开发中见过它,但是在PHP中这似乎是常见的做法。这背后的原因是什么,如果我不能防止这种情况发生,我还应该考虑什么?
解决方案
好吧,这是为了防止敏感内容直接发送到Web服务器。这当然不是一个全面的安全措施,但是它可以进行特定的设置。
但是,如果用户可以从自己的脚本中包含文件,则完全没有帮助
它不仅是php中的安全功能,还是更多基于MVC的PHP站点起作用的功能。例如,如果在SugarCRM中直接调用模块文件,则页面加载将失败,因为以前未加载控制器,视图和模型,并且我们也没有数据库配置/连接信息,因此请确保所有依赖项都已加载用户被迫通过一个已知的入口点,即index.php
我发出一个404页,不是作为一种严格的安全措施,而仅仅是因为我不喜欢泄露有关网站内部的信息,甚至是内部文件的名称。
但是,如果文件仅包含函数,则省略检查并没有真正的危害。
我刚刚在.Net MVC系统中找到了一种方法,可以使用Apache Rewrites,.htaccess文件或者如果使用IIS(即web.config文件)为PHP复制该方法。
由于MVC模式不需要用户直接访问aspx文件,因此不会提供这些文件,而是发送404. 例如,如果我们对包含文件" inc.php"具有命名约定,则可以将* .inc.php请求重定向到Apache中特定文件夹的404重写规则末尾的供应R = 404会将HTTP状态返回到客户。
其中一些示例可能会有所帮助:Apache Rewrite示例
在PHP中比其他类似语言更常见的原因与PHP的历史有关。 PHP的早期版本默认将" register_globals"设置设为打开(实际上,在早期版本中甚至可能没有设置)。 Register_globals告诉PHP根据查询字符串定义全局变量。因此,如果我们这样查询这样的脚本:
http://site.com/script.php?hello=world&foo=bar
...脚本将自动定义值为$ world的变量$ hello和值为bar的$ foo。
对于这样的脚本,如果我们知道键变量的名称,则可以通过在查询字符串上指定这些变量来利用脚本。解决方案?在核心脚本中定义一些魔术字符串,然后使所有辅助脚本检查该魔术字符串,并在不存在的情况下提供援助。
幸运的是,几乎没有人再使用register_variables了,但是许多脚本的编写仍然很差,并且做出了愚蠢的假设,如果在上下文之外调用它们会造成损害。
就个人而言,我通过使用Symfony框架避免了整个事情,该框架(至少在其默认设置中)使控制器和模板完全脱离了Web根目录。唯一的入口点是前端控制器。
如果我们包含来自外部Web根的所有内容,那么这将不是问题,因为无法直接加载任何内容。
正如其他一些答案中已经提到的那样,我们不需要这样做。如果不应由Web服务器提供文件,则不应将其保留在Web文件夹中。 includes应该放在网络根目录之外的目录中。
除此之外,告诉用户页面不存在的正确方法是发出状态404,方法是:
header("HTTP/1.0 404 Not Found"); exit;
如果我们不这样做,那么非人类人员(例如搜索引擎)很难区分常规页面和非页面。
这非常重要,因为如果我们正在编辑运行Google工具栏的网站,它将找到我们内部的php文件,然后将其放入搜索结果中。充其量这会给用户带来尴尬的体验,但是如果我们是一个草率的程序员,则可能会泄露数据库连接信息。