我不知道这是否会发生,但我会尝试。
在过去的一个小时里,我研究了图像上传安全性。我了解到有很多功能可以测试上传。
在我的项目中,我需要确保上传的图像是安全的。此外,可能会有大量图像,并且可能需要大量的带宽,因此购买API不是一个选择。
因此,我决定获得一个完整的PHP脚本,用于真正安全的图像上传。我还认为它将对许多人有所帮助,因为很难找到真正安全的上传脚本。但我不是php专家,因此添加一些功能对我来说真的是个头疼的问题,所以我会请求这个社区的帮助,创建一个真正安全的图像上传完整脚本。
这段文字的意思是:这里有一些非常棒的关于图片上传安全检查列表的主题(然而,它们只是告诉我们需要做什么,而不是如何做到这一点,正如我所说,我不是PHP大师,所以我不能独自完成所有操作): PHP 图片上传安全检查列表 https://security.stackexchange.com/questions/32852/risks-of-a-php-image-upload-form
总的来说,它们告诉我们安全上传图片需要以下步骤(我将引用以上页面的内容):
使用.httaccess禁止在上传文件夹内运行PHP。 如果文件名包含字符串“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。这是其中的一部分,但还不是全部。(如果您知道更多有助于使上传更安全的信息,请分享。) 目前我们拥有的是:
Main 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; }
And the form:
<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>
<?php echo $_SERVER['PHP_SELF']; ?>
不是完全安全的,容易受到跨站脚本攻击。 - Raymond Nijland