c# - 如何过滤上传或发布到 php 网络服务器的文件的扩展名?
问题描述
我用c#做了一个post函数来发送文件到webserver(php),每个上传的文件都没有被扩展过滤,我担心如果有坏人上传恶意文件,比如webshells或其他恶意软件到我的网络服务器。我只想要一个可以通过“发布”功能上传的扩展名 (.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();
}
}
解决方案
正如评论中指出的那样 - 仅仅因为文件声称具有特定扩展名并不意味着它一定是那种类型。然而,一些过滤可以通过做一些如下的处理来实现。测试扩展预期的 mimetype、大小以及每个.lic
文件是否具有相似的标题,您可以测试实际文件本身的一部分 - 尽管文件sha1
或md5
校验和也可能有用。
<?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() ) );
}
?>
推荐阅读
- java - QueryDsl SQL - 左连接子查询
- python-3.x - 使用 pyinstaller 编译代码时 Python exec() 不起作用
- c# - 当有更多值时如何从字典中获取值
- python - 在后台为 GUI 运行函数
- r - 如何使用 ggplot2 stat_smooth 绘制具有随机效应的 glmer 模型?
- ruby - 如何在当前 shell 的上下文中执行 Ruby 系统调用
- python - if 语句中的多个条件在使用字符串时不起作用
- azure-ad-b2c - Azure B2C 不适用于本机客户端应用程序
- spring-boot - 如何在 application.yml 中指定 logback 滚动附加程序?
- laravel - 如何将数据传递到同一函数中的 2 个表