这个函数用于确保由文件名指定的文件是有效的上传文件(也就是通过PHP的HTTP POST上传机制上传的)。如果文件是有效的,它将被移动到指定的文件名。
如果上传文件可能会向用户或甚至同一系统上的其他用户公开其内容,则此类检查尤为重要。
因此,它确保它是由PHP上传的,但如果不进行检查会发生什么?可能会泄露哪些信息以及如何泄露?
有人能解释一下吗?举个例子会更好。
一个PHP脚本可能会移动一些在运行时确定名称的文件(刚刚上传的临时文件的名称)。这个检查旨在确保编写不良的脚本不会暴露系统文件或包含认证密钥的文件。
假设我编写了一个脚本,允许您将图像上传到我的服务器,通过嵌入一些我提供的超可爱的猫咪gif来增强它,并再次下载它。为了跟踪您正在处理的图像,我将文件名嵌入请求URL中以供编辑按钮使用:
http://example.com/add-kitty.php?img=ato3508.png&add=kitty31.gif
或者我将同样的信息嵌入到cookie或POST数据中,错误地认为这样会使其更加安全。然后一些有进取心的脚本小子试着去获取它(或者使用POST/cookie的等效方法):
http://example.com/add-kitty.php?img=$2Fetc%2Fpasswd&add=kitty31.gif
看到了吗?那就是路径/etc/passwd
,经过url编码。糟糕!你可能刚刚使你的/etc/passwd
文件可以下载,并且中间还有一点小猫咪的声音。
显然这不是任何东西的完整工作漏洞,但我相信你已经明白了:函数move_uploaded_file
会进行额外的检查,以保护您免受将意外文件名注入到您的代码中的攻击。
在这种情况下,安全问题是上传目录将对公众可见。
为了避免这种情况,您需要配置您的Web服务器(如Apache),使目录对公众不可见。
此外,每当您通过PHP脚本上传文件时,请使用混合字符重命名文件。
例如,您可以使用加密时间戳与实际文件名相结合。
处理文件上传似乎是常规的。您可以坚持使用这种方式来安全地处理文件上传。
编辑:
根据您在评论中提出的问题,此答案已进行编辑。
您需要在任何www目录中拥有现有文件,以使用rename($existing_old_file_name, $new_file_name)
函数将其重命名。
move_uploaded_file($tmp_uploaded_file_name, $new_file_name)
函数将上传的文件从临时目录移动到您在函数中指定的目标位置。
move_uploaded_file
时也会遇到这些问题。我的问题是为什么不使用rename
呢? - HTMHellrename()
函数重命名它。move_uploaded_file()
函数将上传的文件从tmp目录移动到您在该函数中指定为第二个参数的目标位置。 - Wolverinerename
函数您还可以将文件从临时目录移动到目标文件夹,方法如下:rename($tmp_uploaded_file_name, $new_file_name)
。 - HTMHellrename()
函数无法正确上传图像文件,而且在函数的第一个参数中,您需要指定已上传的tmp文件名作为源的绝对tmp目录,目标可以是绝对路径或相对路径。 - Wolverine
/img
文件夹中。在 PHP 进行进一步处理、保护、验证内容和名称、重命名之前,图像将已经可用。 - arkascharename
而不是move_uploaded_file
。 - HTMHellrename
或move_uploaded_file
都无所谓,文件都会上传到同一个临时文件夹。(rename
还可以在不同驱动器之间移动文件)。这很重要,因为我想知道它可能会引起哪些安全漏洞。 - HTMHellrename()
函数,那么我假设该特定函数进行了额外的验证:移动/重命名的文件实际上是当前请求中上传的文件之一。但是正如我所说的:我只是假设。您必须查看实现以确保。 - arkascha