Bypassing forms input fields to upload unwanted fi

2019-07-25 08:32发布

问题:

My website having uploading profile image section for members and i've used the following code.

Form Code

<form action="send.php" method="post" enctype="multipart/form-data" name="send" id="send">
    Your Image : <input type="file" name="pic" id="pic"/>
    <input type="Submit" name="Submit" value="Submit"/>
</form>

PHP Code send.php

$ImageName = $_FILES[pic][name]; 
if(!empty($ImageName) && $_FILES[pic][type] == "image/jpeg" || $_FILES[pic][type] == "image/png" || $_FILES[pic][type] == "image/gif" || $_FILES[pic][type] == "image/bmp"){
    $t = time();
    $NewImageName = "$t$ImageName"; // image new name
    copy($_FILES[pic][tmp_name], "users/$NewImageName"); // copy it to directory
} else {
    echo "no upload done";
}

But someone by using firefox extension manage to bypass it and uploaded php file Who uploaded the file to my website sent me message said "you only check for type !" and said " i used firefox extension that can fake input fields and passed PHP file ".

So my question how do i protect my image upload form of the above code ? ~ thanks

回答1:

First I don't think that's is the valid format to read $_FILE variable

$ImageName = $_FILES[pic][name]; 

You should use

$ImageName = $_FILES['pic'][name];

Then I think it is improbable that someone can fake a server side check.

Try to hack this, I use a *PATHINFO_EXTENSION* as mentioned in PHP.net Manual

$validFormat = array("jpg","JPG","jpeg","JPEG","png","PNG","gif","GIF");    
$path = pathinfo($_FILES['pic']['name'], PATHINFO_EXTENSION);
if(in_array($path, $validFormat)){
// it's okay
}else{
// Error
}

I'm working with this code since I discovered pathinfo a while ago and nobody hack it..



回答2:

The "type" entries in the $_FILES array are indeed just values that the client sent. Do not trust them.

files are executed as php not based on the MIME type given by the client (or the MIME type that is recognized from their data), but simply by their extension.

$imageName = $_FILES['pic']['name'];

if (isset($imageName)) {
    $ext = pathinfo($imageName, PATHINFO_EXTENSION);
    if (in_array(strtolower($ext), array('jpg', 'jpeg', 'gif', 'png', 'bmp')) {
        $t = time();
        $newImageName = $t . basename($imageName);
        copy($_FILES['pic']['tmp_name'], 'users/' . $newImageName);
    }
} else {
    echo 'no upload done';
}

Note the invocation to pathinfo to get the extension, and basename to avoid path traversal attacks.



标签: php security