【问题标题】:Forcing file-creation in public directory?强制在公共目录中创建文件?
【发布时间】:2012-04-20 15:28:58
【问题描述】:

这是一个想法。我正在尝试从 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 是否指向服务器的公共目录之外。

简而言之,如果文件不存在,或者文件存在并且$owerwrite=true,我希望这个函数创建文件并返回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;
    }

【问题讨论】:

  • 文件无法创建有以下几个原因:权限错误、磁盘已满、磁盘挂载只读、挂载点不存在、如果是网络共享可能有网络上的东西、磁盘已损坏,文件系统有问题..内核问题..许多其他事情。关于限制公共目录下的文件位置,您当然可以将公共路径添加到给定路径,然后检查文件路径中是否存在某些“..”,在这种情况下返回 false。
  • @kappa,感谢您的信息。顺便说一句,“..”也是 $path 参数的有效部分,但前提是它不指向公共目录之外。

标签: php security file-io filesystems chmod


【解决方案1】:

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

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

  2. 您可能没有正确使用/传递参数/参数。

【讨论】:

    【解决方案2】:

    一些建议:

    1. 设置 web 服务器文档根目录的所有者: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

    【讨论】:

    • 这真是个糟糕的建议! chmod -R 755 将使 所有文件 可由 PHP 写入,而不仅仅是目录!然后只需要一个与文件相关的漏洞就可以让攻击者重写您的代码
    • @Jon 你是对的。 -R 选项很危险:755 仅适用于目录!对于这些目录中的文件 555 应该足够好了!
    • 1) 我明白,但函数体是我所拥有的,其他配置/设置是不允许的。一切都必须在这个函数内完成(当然,如果可能的话)。 2) 路径“/var/www/../../../etc/passwd?”显然是不正确的,因为它指向公共目录之外(在这种情况下函数必须返回 false)。 3) 我知道。为您的努力 +1。
    猜你喜欢
    • 2016-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    相关资源
    最近更新 更多