PHP中的move_uploaded_file函数为什么很重要?

4
我无法想象为什么我要使用这个函数而不是简单的重命名。
手册写道:
move_uploaded_file 此函数检查 filename 指定的文件是否是有效的上传文件(也就是说,它是通过PHP的HTTP POST上传机制上传的)。如果文件有效,则会将其移动到 destination 指定的文件名中。
如果有任何可能使上传文件的任何内容暴露给用户甚至同一系统上的其他用户的情况,这种检查尤其重要。
能否请您举个例子说明为什么这么重要?

3个回答

5

使用常规的文件系统函数可能会创建安全漏洞。如果您在程序中这样做:

rename($source, $destination);

如果攻击者能够控制$source的值,他们就能够重命名(或移动!——rename还可以将文件移动到其他目录)PHP进程可以访问的任何文件。
如果他们还能够影响$destination,或者在文件被移动后以某种方式获得文件内容的访问权限,他们就可以利用这个漏洞来获取您的源代码,至少会泄露身份验证凭据。而且很容易想象这种情况发生:如果您接受用户上传并使它们通过URL可访问,这个功能已经内置在您的应用程序中。
总之,这是一个必须考虑的安全问题;_uploaded_file函数的存在是为了帮助您陷入成功的深渊
更新(从评论中提取的材料):
现代文件上传处理(通过$_FILES)已经基本上不需要使用move_uploaded_file。但不要忘记:
  • 从技术上讲,不必要的措施仍然是一个好主意:我们正在谈论安全,为什么不再多一份保险呢?
  • move_uploaded_files 是在 $_FILES 甚至不存在的时候引入的,而广泛使用 register_globals 而不是童话故事。

1
攻击者能够控制$source的值 - 这是一个巨大的假设...源文件名是由PHP自动生成的,无法从外部进行控制,它是一个随机数。因此我并不信服。 - inf3rno
1
@inf3rno:如果 $source 是在PHP应用程序中生成的,那么对你来说很好,你不需要使用 move_uploaded_file。但是这个功能并不是专门针对你或者你正在考虑的特定代码块的。 - Jon
3
@inf3rno说:$_FILES的人口是PHP的一个特性。rename函数的第一个参数直接来自于$_FILES内部是因为你的代码而不是其他人的代码。此外,move_uploaded_file函数早在$_FILES出现之前就存在了,并且在那个时候,register_globals仍然存在。因此,今天看来它似乎并没有那么有用,但它已经存在很长时间了。 - Jon
哈哈,lol,你说人们通常不用 $_FILES 超全局变量来移动他们上传的文件... 真是神奇... - inf3rno
2
php.init文件包含一个选项“open_basedir”(http://www.php.net/manual/en/ini.core.php#ini.open-basedir),使用它可以防止PHP应用程序读取其根目录外的文件,在这种情况下,只有move_upload_file可以从/tmp目录中读取上传的文件。它提高了安全性,因为它保护了同一服务器上的网站互不干扰,或者上传的恶意脚本破坏的不仅仅是它被上传的应用程序。 - Hermann Stephane Ntsamo
显示剩余2条评论

-2

move_uploaded_file 实际上会将您上传的文件从临时目录移动到服务器上的永久位置。是的,这很重要,因为您必须将文件移动到指定的服务器位置,对吧?

在这里检查 move_uploaded_file 的代码片段示例: http://www.developphp.com/view_lesson.php?v=449


我也可以使用常规的PHP文件函数来移动它。 - inf3rno
move_uploaded_file()确保安全,只允许移动通过PHP上传的文件。因此它是专门用于移动已上传文件的功能。 - Kalpesh

-2

您不应该使用rename函数,因为rename函数用于将现有文件重命名为新名称。而像move_uploaded_file和copy这样的函数实际上是用于将文件从tmp目录上传到目标目录。

rename()应该用于移动普通文件,而不是通过表单上传的文件。原因是有一个特殊的函数叫做move_uploaded_file(),它会检查文件是否已经被上传,然后再移动它 - 这可以防止人们试图入侵您的服务器以使私有文件可见。如果您愿意,您可以通过调用is_uploaded_file()函数来执行此检查。


1
重命名:尝试将旧名称更改为新名称,必要时将其移动到其他目录。如果新名称已存在,则会被覆盖。 - inf3rno
我已经知道上传的函数是推荐的,但是我不明白为什么。 - inf3rno
如果更新后的答案没有给你一个想法,那么你需要重新阅读它 :) - chandresh_cool

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接