强制在公共目录中创建文件?

时间:2012-04-07 09:07:10

标签: php security file-io filesystems chmod

这是一个想法。我正在尝试从PHP脚本创建文件。可以在服务器上的任何公共场所(在公共根目录或其子目录中)创建文件。最后,我想编写这样的函数(它必须在unix和windows服务器上运行)。

function create_file($path, $filename, $content, $overwrite=false) {
  # body
  ...

  }

参数:

  • $ path - 文件路径(空或以/结尾)
  • $ filename - 任何有效的文件名(需要点+扩展名)
  • $ content - 文件内容(任何内容)
  • $ overwrite - 如果设置 true ,现有文件将被覆盖(默认为 false )。

结果:

函数返回TRUE并创建包含内容的文件,如果由于任何原因无法创建文件,则为FALSE

问题描述:

我希望此功能返回true并在路径 $ path 上创建文件 $ filename ,如果不可能,则为false无论如何。此外,如果文件成功打开以进行编写,则需要在其中加入 $ content

参数 $ path 是公共目录的相对路径, $ filename 是任何有效的文件名。当然,如果路径点在公共目录之外,我想避免创建文件。可以从子目录脚本调用函数,如此示例

# php script: /scripts/test.php
create_file('../data/', 'test.info', 'some contents');
# result file: /data/test.info

到目前为止我尝试了什么?

我尝试使用fopen()fwrite()函数执行此操作,这在某些服务器上有效,但在某些服务器上无效。我想编写权限和chmod()有问题,但说实话,我对chmod属性不是很熟悉。此外,我无法检查 $ path 是否位于服务器的公共目录之外。

简而言之,我希望此函数创建文件并返回TRUE如果文件不存在,或文件存在且$owerwrite=true。否则,没有任何反应,函数返回FALSE

此外,我想知道为什么无法在某些路径上创建文件(理论上)。错误的路径/文件名只是我的想法,我确信这个问题还有更多。

提前感谢任何样本/示例/建议。

更新代码

到目前为止,我有这段代码......

  function create_file($path, $filename, $content, $overwrite=false) {
    $reldir = explode('/', trim(str_replace('\\', '/', dirname($_SERVER['PHP_SELF'])), '/'));
    $dirdepth = sizeof($reldir);
    $rpadd = $dirdepth > 0 ? '(\.\./){0,' . $dirdepth . '}' : '';
    $ptpath = '#^/?' . $rpadd . '([a-z0-9]\w*/)*$#i';
    $ptname = '/^[a-z]\w*\.[a-z0-9]+$/i'; 
    if ($res = preg_match($ptpath, $path) && preg_match($ptname, $filename)) {
      $res = false;
      if ($overwrite === true || !file_exists($path.$filename)) {
        if ($f = @fopen($path.$filename, 'w')) {
          fwrite($f, $content);
          fclose($f);
          $res = true;
          }
        }
      }
    return $res;
    }

2 个答案:

答案 0 :(得分:2)

一些建议:

  1. 设置Web服务器文档root的所有者:chown -R apache:apache / var / www(我假设/ var / www是您的文档根目录,而Web服务器apache是​​使用用户apache运行的)。像这样设置文档根目录的权限,以使文档下的所有目录都显示特权755(只有用户apache的所有者可以写入文件夹/ var / www和子文件夹)
  2. 阻止指向/ var / www文档根目录的路径:您处于称为http://en.wikipedia.org/wiki/Directory_traversal_attack的问题之下。如果$ path类似于:/var/www/../../../etc/passwd怎么办? Basename php功能可以帮助您识别这种恶意路径。看这篇文章:php directory traversal issue
  3. 检查文件是否已存在:http://php.net/manual/en/function.file-exists.php

答案 1 :(得分:0)

php中的所有文件函数在两种情况下都无法正常工作

  1. 如果您没有足够的应用程序用户权限,那么

  2. 您可能无法正确使用/传递参数/参数。