【问题标题】:How do I get around apache owning files uploaded to a PHP webserver?如何绕过 apache 拥有上传到 PHP 网络服务器的文件?
【发布时间】:2011-03-26 05:21:49
【问题描述】:

我正在 Linux 网络服务器上开发一个 PHP 网络应用程序,以获取我正在共同教授的课程的成绩和文档。我现在写的页面是提交作业的,学生从下拉菜单中选择一个作业,然后上传作业并提交。提交时,有关提交的所有信息都进入 MySQL 表,并且文件被移动到文件系统上的永久位置。理想情况下,这将是按作业、学生和版本高度组织的东西,但我现在只想让文件上传在原则上正常工作,所以现在它只是将东西发送到目录 ~/phptest/ (权限设置为 755,尽管我尝试 777 只是为了进行测试,但这也不起作用)。这是现在的代码:

($dbh 是我创建的扩展数据库句柄类的一个实例,以使这些特定的数据库事务更清晰)


if(isset($_POST['submit'])) {
    $assignmentID = $_POST['assID'];
    $tmp = "/home/username/phptest/"; 
    $info = pathinfo($_FILES['file']['name']);
    $filename = $info['basename'];
    $ext = $info['extension'];
    if(1) { //strcmpall($ext,array('tar.gz','zip'))) {
        if($_FILES['file']['size'] < 1000000) {
            $path = $tmp . $filename;
            if(move_uploaded_file($_FILES['file']['tmp_name'], $path)) {
                $versionQuery = $dbh->select(array('version'),array('a01_submissions'),array("studentID='$studentID'","assignmentID='$assignmentID'"));
                if(count($versionQuery)) {
                    $versionArray = $dbh->colToArray($versionQuery,'version');
                    $version = max($versionArray)+1;
                }
                else $version = 1;
                echo "Version $version.\n";
                $week = $dbh->getOne('week','a01_assignments','id',$assignmentID);
                $dbh->insert("a01_submissions",array('studentID','assignmentID','version','filePath'),array($studentID,$assignmentID,$version,addslashes($newpath)));
                echo "File $filename sucessfully uploaded and stored at $newpath.\n";
            }
            else echo $moved . "
\n"; } else die("File cannot exceed 1MB"); } else die("Bad file extension."); } else { // HTML to display the submission screen }

不过,我的问题是 move_uploaded_file 仅适用于具有 777 权限的目录。仔细检查表明这是因为 PHP 正在以用户 'apache' 的身份上传内容,因此无法使用 o-w 写入我的用户名拥有的目录。我看到用户在 PHP 文档中发布的解决方案建议使用 chown 来回收文件,但我没有足够高的权限级别来执行此操作。对于这个问题,是否有一个优雅的解决方案,不涉及尝试让我的用户名获得更高权限?

【问题讨论】:

    标签: php apache file-upload chmod


    【解决方案1】:

    让系统管理员将您与 apache 放在同一个用户组中,或者最好创建一个名为开发人员之类的新组,然后将 apache 用户和您自己添加到其中。

    否则,您可以在文件上传后立即尝试使用 PHP 的 chmodchown 函数。如果你运行chmod($filepath, 0777);,那应该是一个很好的测试它是否适合你。

    【讨论】:

    • 如果我想使用 755,那不会仍然阻止来自同一组中的用户的写入吗? 755是g-w和o-w。还是说如果组只包含我的用户名和 apache,775 和 755 一样好?
    • 755 不能作为同一组的成员进行写作。您将需要使用 764 或更高版本(例如 775 或 765)。请参阅:csgnetwork.com/csgchmodcalc.html 了解解决此问题的简单方法。
    • 不,我了解权限位是什么,我只是担心安全性。您是说限制“其他人可写”位是否足够安全?我一直认为黄金标准是 755,所以我想知道是否有任何方法可以对 r-x 的团队和其他人做我想做的事情。或者,更好的问题是什么是做我想做的最安全的方法?
    • 如果你需要写,那么你需要写,所以你必须设置烫发——我不明白你怎么能绕过那么短的时间,把它变成 755,然后把文件复制到你的自己的用户目录进行操作。
    【解决方案2】:

    简短回答:没有优雅的解决方案,因为这在概念上是错误。文件首先归 Web 服务器用户所有是有原因的。它是创建文件的网络服务器(从操作系统的角度来看),所以他应该拥有它。

    长答案: 您确实希望文件归其他用户所有的原因是什么?

    1. 安全性 好吧,只要文件不再属于网络服务器,它就不能被它覆盖,所以如果攻击者接管了网络服务器,他或她就不能改变分配不再。的确。但是,Web 应用程序不应该做 Weird Stuff™,而是应该专注于它应该做的事情,并且保护 Web 服务器肯定不是它的任务之一。一个适当的应用程序架构和一些标准的安全措施应该做同样的伎俩,并且本质上比仅仅改变文件的所有者拥有更多的安全性。如果您必须移动数据,您可以使用incroninotincoming 之类的工具设置监视文件夹。如果您的安全需求很高,您应该考虑在您的网络服务器上实施 SELinux 配置文件。
    2. 底层业务逻辑 自己实现复杂的工作流程是个坏主意。如果您有关于文档处理的其他业务逻辑,我建议使用Apache CamelApache Servicemix,后者又使用 Camel,但提供了更多功能。 Apache camel是一个Wrouting and mediation engine”,大致翻译为“它根据Enterprise Integration Patterns处理消息。这反过来意味着它转换、拆分、丰富、路由或过滤任何给定的有效负载。有一个出色的file processing module,它可以自动执行许多您在实现业务逻辑(处理、恢复中断处理、创建备份等)时必须自己处理的事情。 Camel supports php too(虽然我不建议首先使用 php,但这是完全有偏见的)。你可以用 incron 或 inotincoming 链接它
    3. 访问 您可能希望通过 ftp 访问这些文件,但不将 ftp 用户添加到 Web 服务器组。简单的解决方案:使用“其他”权限。设置对方的权限并不是在互联网上广播文件。确保您对“其他”集具有只读权限,并且一切顺利。另一种解决方案可能是使用虚拟用户设置 ftp 服务器。

    底线:总是有一个解决方案而不会破坏感觉,更不用说实施安全措施了。

    【讨论】:

      猜你喜欢
      • 2016-01-19
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      • 2013-05-28
      • 1970-01-01
      • 1970-01-01
      • 2015-11-04
      相关资源
      最近更新 更多