完全安全的映像上传脚本
我不知道这是否会发生,但我会尝试一下。
在过去的一个小时里,我对图像上传的安全性进行了研究。我了解到有很多函数可以测试上传。
在我的项目中,我需要安全地上传图像。也可能有非常大的数量,它可能需要很多带宽,所以购买API不是一种选择。
所以我决定获得一个完整的PHP脚本,用于真正安全的图像上传。我也认为这对许多人都有帮助,因为不可能找到真正安全的。但我不是php的专家,所以添加一些功能对我来说真的很头疼,所以我会要求这个社区帮助创建一个真正安全的图像上传的完整脚本。
关于这个问题的真正伟大的主题在这里(但是,他们只是在告诉做这个技巧需要什么,而不是如何做到这一点,正如我所说,我不是PHP的大师,所以我不能自己做到这一点):PHP图像上传安全检查列表 https://security.stackexchange.com/questions/32852/risks-of-a-php-image-upload-form
总而言之,他们告诉这是安全图像上传所需要的(我将引用上面的页面):
- 禁止 PHP 在上传文件夹中使用 .httaccess 运行。
- 如果文件名包含字符串“php”,则不允许上传。
- 只允许扩展名:jpg,jpeg,gif和png。
- 仅允许图像文件类型。
- 禁止具有两种文件类型的图像。
- 更改映像名称。上传到子目录而不是根目录。
也:
- 使用 GD(或 Imagick)重新处理图像并保存处理后的图像。所有其他的只是黑客的乐趣无聊”
- 正如rr所指出的,使用move_uploaded_file()进行任何上传”
- 顺便说一句,您希望对上传文件夹进行非常严格的限制。这些地方是发生许多漏洞的黑暗角落之一
。这适用于任何类型的上传和任何编程语言
/服务器。检查
https://www.owasp.org/index.php/Unrestricted_File_Upload- 级别 1:检查扩展名(扩展名文件以结尾)
- 级别 2:检查 MIME 类型 ($file_info = getimagesize($_FILES['image_file']; $file_mime = $file_info['mime'];)
- 级别 3:读取前 100 个字节并检查它们是否有任何字节位于以下范围内:ASCII 0-8、12-31(十进制)。
- 级别 4:检查标头中的幻数(文件的前 10-20 个字节)。你可以从这里找到一些文件头字节:
http://en.wikipedia.org/wiki/Magic_number_%28programming%29#Examples- 您可能还想在 $_FILES['my_files'] ['tmp_name'] 上运行“is_uploaded_file”。查看
http://php.net/manual/en/function.is-uploaded-file.php
这是其中很大一部分,但这还不是全部。(如果您知道更多有助于使上传更加稳定的东西,请分享。
这就是我们现在得到的
-
主要 PHP:
function uploadFile ($file_field = null, $check_image = false, $random_name = false) { //Config Section //Set file upload path $path = 'uploads/'; //with trailing slash //Set max file size in bytes $max_size = 1000000; //Set default file extension whitelist $whitelist_ext = array('jpeg','jpg','png','gif'); //Set default file type whitelist $whitelist_type = array('image/jpeg', 'image/jpg', 'image/png','image/gif'); //The Validation // Create an array to hold any output $out = array('error'=>null); if (!$file_field) { $out['error'][] = "Please specify a valid form field name"; } if (!$path) { $out['error'][] = "Please specify a valid upload path"; } if (count($out['error'])>0) { return $out; } //Make sure that there is a file if((!empty($_FILES[$file_field])) && ($_FILES[$file_field]['error'] == 0)) { // Get filename $file_info = pathinfo($_FILES[$file_field]['name']); $name = $file_info['filename']; $ext = $file_info['extension']; //Check file has the right extension if (!in_array($ext, $whitelist_ext)) { $out['error'][] = "Invalid file Extension"; } //Check that the file is of the right type if (!in_array($_FILES[$file_field]["type"], $whitelist_type)) { $out['error'][] = "Invalid file Type"; } //Check that the file is not too big if ($_FILES[$file_field]["size"] > $max_size) { $out['error'][] = "File is too big"; } //If $check image is set as true if ($check_image) { if (!getimagesize($_FILES[$file_field]['tmp_name'])) { $out['error'][] = "Uploaded file is not a valid image"; } } //Create full filename including path if ($random_name) { // Generate random filename $tmp = str_replace(array('.',' '), array('',''), microtime()); if (!$tmp || $tmp == '') { $out['error'][] = "File must have a name"; } $newname = $tmp.'.'.$ext; } else { $newname = $name.'.'.$ext; } //Check if file already exists on server if (file_exists($path.$newname)) { $out['error'][] = "A file with this name already exists"; } if (count($out['error'])>0) { //The file has not correctly validated return $out; } if (move_uploaded_file($_FILES[$file_field]['tmp_name'], $path.$newname)) { //Success $out['filepath'] = $path; $out['filename'] = $newname; return $out; } else { $out['error'][] = "Server Error!"; } } else { $out['error'][] = "No file uploaded"; return $out; } } if (isset($_POST['submit'])) { $file = uploadFile('file', true, true); if (is_array($file['error'])) { $message = ''; foreach ($file['error'] as $msg) { $message .= '<p>'.$msg.'</p>'; } } else { $message = "File uploaded successfully".$newname; } echo $message; }
-
形式:
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data" name="form1" id="form1"> <input name="file" type="file" id="imagee" /> <input name="submit" type="submit" value="Upload" /> </form>
因此,我要求通过发布代码片段来提供帮助,这将有助于我(和其他人)使此图像上传脚本变得超级安全。或者通过共享/创建一个完整的脚本,并添加所有代码段。