【问题标题】:separate php file as template - security hazard?单独的 php 文件作为模板 - 安全隐患?
【发布时间】:2009-12-22 20:53:29
【问题描述】:

我正在研究 php 的模板系统,我开始相信纯 php 代码似乎是我想要使用的解决方案。

我是唯一的开发者,所以没有设计师需要一个被削弱的竞技场来工作。像 smarty 这样的模板引擎似乎受到“内部平台效应”的影响。如果我坚持良好的做法(预先计算的值,仅使用 foreach ),我认为这会奏效。

我的目标是为每个页面共享的 html 字符串提供单一来源。我的想法是一个单独的 php 文件,通过 include 访问,是实现这个目标的好方法。

但是,我担心这可能会给网站带来安全隐患——我目前想不出任何具体的内容,但有人可能会猜到模板的名称并直接请求它,可能会暴露一些东西他们不需要看到。 (我想我可以检查一下它本身是否是请求。)我有预感这可能很糟糕,所以我不想继续这样做,创造我担心会发生的事情,然后把那个工作扔掉。

如果单独的文件不是最好的主意,我还应该使用什么来基本上存储整个站点的字符串?包含中的字符串常量,我可以在 sprintf() 中使用吗?从页面特定的 html 部分的参数返回 html 字符串的函数?

【问题讨论】:

    标签: php templates security


    【解决方案1】:

    不应通过 HTTP 提供的文件应存储在一个目录中,您的网络服务器将不允许从该目录中向用户提供任何(至少不是 PHP)

    两种可能:

    • 将这些文件放在DocumentRoot 之外
    • 或将这些文件放在子目录中,Apache 将无法从中提供任何文件。

    此类“未提供”文件通常包括以下内容:

    • 配置文件
    • 库/框架
    • 数据文件(例如 SQLite 数据库;或 i18n 文件)


    第一个解决方案:您的目录可能如下所示:

    • data/
      • i18n/
      • i18n/your-file-here.php
    • library/
    • www/         
      • index.php
      • another-php-file.php


    对于第二种解决方案,只需禁用对包含“数据”或“库”文件的目录的访问,在其中放入一个 .htaccess (如果您的网络服务器是 Apache) 包含类似内容的文件 p>

    Deny From All
    

    这样,Apache 将不允许任何人通过 HTTP 直接访问该目录中的文件,但您的可执行 PHP 脚本(在另一个目录中) 仍然能够包含它们。

    【讨论】:

    • +1 我会建议第一个,但第二个效果很好。我同意这些。
    • 我更喜欢第一个(这样就不会忘记隐藏的 .htaccess 文件);;但是,对于某些共享托管服务,您不能放置任何“高于” DocumentRoot... 在这种情况下,您不能使用第一个解决方案:-(
    • -1 直到您更改“不应“执行”的文件应存储在您的网络服务器不会解释 PHP 的目录中。”类似于“不应通过网络服务器直接访问的文件应存储在其发布的目录树之外”。从表面上看,您建议在未处理的情况下提供此类 php 模板的设置,从而泄露源代码。这比让它们暴露但处理要严重得多。
    • @just someone :我已经编辑了第一句话,试图让它更清楚一点——我在帖子后面添加了一些东西;;希望可以理解^^
    【解决方案2】:

    简单,真的;将文件命名为您想要的任何名称,但使用“.inc.php”作为扩展名,然后在文件顶部包含此行:

    if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME'])) {
        die;
    }
    

    如果直接访问文件,这将终止脚本。

    编辑:Pascal Martin 的解决方案可能更符合 BCP,而我的解决方案更加快速和肮脏。两种我都用过,感觉都不错。

    【讨论】:

    • 我喜欢这个,因为功能在页面中,并且随它一起移动。 .htaccess 文件可能会丢失——它已经不可见了!
    • 什么是 BCP?评论中需要 15 个字符。
    • 无论是“最佳常见做法”还是“最佳当前做法”,它们的意思都是一样的:我们知道如何做和现在正在做的最好的事情。
    • 我接受了马丁的回答,但我还是喜欢这个。这一切都将功能保存在一个单元中,并且使用与 php 相同的语言,而不是将功能分解为另一种文件和语言。
    【解决方案3】:

    我也喜欢使用单独的模板文件。通常我会在我的配置文件中定义一个常量,然后在包含的文件的顶部对该常量进行检查,如下所示:

    在配置中设置常量:

    define('_VALIDPAGE', true);
    

    检查包含文件中的常量:

    defined('_VALIDPAGE') or die('Not allowed');
    

    这使得包含的文件只能从您的应用程序中加载。

    【讨论】:

      【解决方案4】:

      你是对的,php 本身就是一个很好的模板系统,只要你在“模板”文件中坚持它的某个子集。但坚持每个网页使用一个模板是不切实际的:您通常会发现片段在多个模板上重复。

      无论如何,单独的文件很好。根据我的经验,将模板放入与源目录(树)分开的目录(树)中是个坏主意:概念上的距离越来越大,你看不到真正使用的东西和没有使用的东西,结果,你有很多模板已经死了但没有被埋葬,因为它们的状态不是那么明显。

      我的建议:将“模板”与“程序”文件放在一起,并使用适当的 Web 服务器配置进行保护

      DocumentRoot /www
      AddType application/x-httpd-php .php
      
      <Files ~ \.tpl$>
       deny from all
      </Files>
      
      /www/
        dir1/
          file.php
          file.tpl
          another-file.tpl
        dir2/
          other-file.php
          other-file.tpl
          yet-another-file.tpl
        ...
        common/
          shared-file.tpl
          another.tpl
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-13
        • 2020-04-14
        • 1970-01-01
        • 2020-01-27
        • 1970-01-01
        • 2021-05-21
        • 2010-09-07
        • 2012-03-28
        相关资源
        最近更新 更多