如何过滤对上传或发布到php Web服务器的文件的扩展名?

时间:2019-02-17 09:24:31

标签: c# php

我使用c#进行了后期处理,将文件发送到Web服务器(php),每个上传的文件都没有通过扩展名过滤,我担心如果有人恶意上传恶意文件(例如webshel​​l或其他文件),恶意软件进入我的Web服务器。 我只想要一个可以通过“发布”功能上传的扩展名(.lic)

(php)
<?php
$uploads_dir = './newfolder';
if ($_FILES["file"]["error"] == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["file"]["tmp_name"];
$name = $_FILES["file"]["name"];
move_uploaded_file($tmp_name, "$uploads_dir/$name");
}
?>

c#
public void upLoad()
    {
        try
        {
            WebClient client = new WebClient();
            string myFile = this.temPfold + "License.lic";
            client.Credentials = CredentialCache.DefaultCredentials;
            client.UploadFile(this.myurl, "POST", myFile);
            client.Dispose();
        }
        catch (Exception)
        {
            Application.Exit();
        }
    }

1 个答案:

答案 0 :(得分:1)

正如评论中指出的那样,

仅仅因为文件声称具有特定的扩展名并不意味着该文件一定是该类型的。但是,可以通过执行以下类似处理来实现某些过滤。测试扩展名预期的模仿类型,大小,并且如果每个.lic文件都具有相似的标头,则可以测试实际文件本身的一部分-尽管文件sha1md5的校验和可能是也使用。

<?php

    try{
        if( !empty( $_FILES['file'] ) ){

            $LIC_MIME_TYPE='text/plain';    # what is the correct mimetype?
            $LIC_MAX_FILE_SIZE=1024;        # how large???
            $dir = './newfolder/';

            $obj=(object)$_FILES['file'];
            $name=$obj->name;
            $tmp=$obj->tmp_name;
            $err=$obj->error;
            $size=$obj->size;
            $mime=mime_content_type( $tmp );


            if( !empty( $err ) )throw new Exception('An error occurred', $err );
            if( !$mime==$LIC_MIME_TYPE )throw new Exception( sprintf( 'Invalid mimetype %s',$mime),400 );

            $ext = strtolower( pathinfo( $name, PATHINFO_EXTENSION ) );
            if( $ext!=='lic' ) throw new Exception('Invalid file extension',400 );
            if( !is_uploaded_file( $tmp ) ) throw new Exception( 'Possible File upload attack', 400 );
            if( $size > $LIC_MAX_FILE_SIZE ) throw new Exception( 'File too large', 400 );

            $status = move_uploaded_file( $tmp, $dir . $name );
            if( !$status )throw new Exception('Failed to Save file',400 );

        }
    }catch( Exception $e ){
        exit( sprintf( '%s [%d]', $e->getMessage(),$e->getCode() ) );
    }
?>