首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP安全图像上传-附加代码?

PHP安全图像上传-附加代码?
EN

Stack Overflow用户
提问于 2015-09-02 02:15:09
回答 1查看 300关注 0票数 1

这是我上传图片文件到php/mysql服务器的代码。我读过类似的帖子和教程,但大多数都说它们并不完整。

这是否足够安全,或者还会缺少什么?

代码语言:javascript
复制
if(isset($_FILES["file"]) && $_FILES["file"]['error'] == 0)
{
$file = $_FILES["file"];

    $file = $_FILES["file"]['name'];
    $file_type = $_FILES["file"]['type'];
    $file = strtolower($file);
    $file_type = strtolower($file_type);

    if(is_array($_FILES["file"]['error'])){
        echo '<a href="cad_p.php">Try again</a>';
        echo "<br/>";
        echo "<br/>";
        die('Erro: Only one file accepted');
    }

    $max_file_size = 2097152;
    if($_FILES['file']['size'] >= $max_file_size || $_FILES['file']['size'] == 0){
        echo '<a href="cad_p.php">Try again</a>';
        echo "<br/>";
        echo "<br/>";
        die('Erro: file size exceeded (2mb)');
    }

    /* check if contain php */
    $pos = strpos($file, 'php');
    if(!($pos === false)) {
        echo '<a href="cad_p.php">Try again</a>';
        echo "<br/>";
        echo "<br/>";
    die('Error: image has php script');
    }

/* finfo */ 
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($_FILES['file']['tmp_name']);
$allowed2 = array('jpg'=>'image/jpeg', 'png'=>'image/png', 'jpeg'=>'image/jpeg');
$ext = array_search($mime, $allowed2, true);

    if(false === $ext){
        echo '<a href="cad_p.php">Try again</a>';
        echo "<br/>";
        echo "<br/>";
    die('FileInfo: Extension not allowed');     
    }

    /* get file extension */
    $file_ext = strrchr($file, '.');

    /* check if it is allowed */
    $allowed = array(".jpg",".jpeg",".png");
    if (!(in_array($file_ext, $allowed))) {
        echo '<a href="cad_p.php">Try again</a>';
        echo "<br/>";
        echo "<br/>";
    die('Extension not allowed');
    }

    /* check upload type */
    $pos = strpos($file_type,'image');
    if($pos === false) {
        echo '<a href="cad_p.php">Try again</a>';
        echo "<br/>";
        echo "<br/>";
    die('error 1: Mime type not valid');
    }

    $imageinfo = getimagesize($_FILES['file']['tmp_name']);
    if($imageinfo['mime'] != 'image/jpeg'&& $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
        echo '<a href="cad_p.php">Try again</a>';
        echo "<br/>";
        echo "<br/>";
    die('error 2: size mime type not valid');
    }

    //check double file type (image with comment)
    if(substr_count($file_type, '/')>1){
        echo '<a href="cad_p.php">Try again</a>';
        echo "<br/>";
        echo "<br/>";
        die('error 3: double type');
    }

    /* upload to upload direcory */ 
    $uploaddir = 'up_files/';

    if (file_exists($uploaddir)) {  
    } else {  
mkdir( $uploaddir, 0777);  
}  
/* change the image name */
$uploadfile = $uploaddir . md5(basename($_FILES['file']['name'])).$file_ext;

if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
    echo "";
} else {
    echo "Error moving image file";
    echo '<a href="cad_p.php">Try again</a>';
}

$name = $_POST['name'];

if ($insert_stmt = $mysqli->prepare("INSERT INTO products (name, file) VALUES (?, ?)")) {$insert_stmt->bind_param('ss', $name, $uploadfile);

if (! $insert_stmt->execute()) {
    echo '<div class="register_success">';
    echo "Could not insert...";
    echo '</div>';
}else{
    echo '<div class="register_success">';
    echo "Product Insert success...";
    echo '</div>'; 
}

}
}
else
{
echo '<a href="cad_p.php">Tente novamente</a>';
echo "<br/>";   
echo "<br/>";   
die('No image file selected');  
}
EN

回答 1

Stack Overflow用户

发布于 2015-09-02 05:23:08

在阅读了PHP手册中的评论后,我发现了一个名为sparticvs的用户的评论。

“注意安全:永远不要相信$_FILES”图像“。它接受浏览器发送的任何内容,所以不要相信图像类型的这一点。我建议使用finfo_open (http://www.php.net/manual/en/function.finfo-open.php)来验证文件的MIME类型。它将解析文件中的魔术,并返回文件可以信任的文件(您也可以在Unix上使用”type...this“程序,但我会避免使用您的PHP代码进行系统调用...这是在自找麻烦)。”

转到这里,向下滚动查看他的评论:http://php.net/manual/en/reserved.variables.files.php

但是,如果您打算使用该解决方案,这里有一些建议:

使用strip_tag()这很有可能有人设法将一些超文本标记语言或PHP标记放入你的代码中。点击此处阅读更多信息:http://php.net/manual/en/function.strip-tags.php

$name =$_POST‘$name’;这似乎很危险。你根本没做任何检查。我再次建议使用strip_tags和类型验证。

编辑:我会将我的老师笔记添加到这个答案中:

  • 通过使用getimagesize()确保它不是假文件,这将在失败时返回false。限制文件大小。
  • 总是检查扩展名,并且只允许你想要的扩展名。
  • 更改文件名或使用

_tags/htmlentities清除文件名。

  • 请勿将文件直接保存到数据库中。
  • 如果文件名中有空格,请对其进行正确编码。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32338352

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档