php上传文件很慢的原因_PHP编码安全:上传文件安全

一次性付费进群,长期免费索取教程,没有付费教程。

进微信群回复公众号:微信群;QQ群:460500587

 教程列表 见微信公众号底部菜单 |  本文底部有推荐书籍 

38321bfaa4a222248e1f3728097a8623.png

微信公众号:计算机与网络安全

ID:Computer-network

在Web系统中,允许用户上传文件作为一个基本功能是必不可少的,如论坛允许用户上传附件,多媒体网站允许用户上传图片,视频网站允许上传头像、视频等。但如果不能正确地认识到上传带来的风险,不加防范,会给整个系统带来毁灭性的灾难。

在PHP项目中,提供上传功能并在服务器端未对上传的文件格式进行合理的校验是存在巨大风险的。如果恶意攻击者利用上传漏洞上传一些webshell,则可能完全控制整个网站程序,执行系统命令,获取数据库链接字串进行操作数据库等危险操作。

1、文件上传漏洞

以下是一个不安全的上传代码示例,即文件上传PHP接收代码upload.php。

$upload_dir='uploads'; // 用户上传文件保存目录

$upload_file=$upload_dir.basename($_FILES['userfile']['name']);

if(move_uploaded_file($_FILES['userfile']['tmp_name'],$uploadfile)) {

echo "恭喜您,文件上传成功";

} else {

echo "文件上传失败";

}

?>

以下是文件上传HTML代码upload.html。

请选择上传文件:

这是一个简单的上传文件功能,其中由用户上传文件,如果上传成功,保存文件的路径为http://服务器路径/uploads/文件名称。

如果攻击者上传一个如下内容的hacker.php脚本文件到服务器:

system($_GET['shell']);

?>

则攻击者就可以通过该文件进行URL请求http://服务器路径/uploads/hacker.php?shell=ls%20-al,从而可以执行任何shell命令。

图1所示是恶意脚本的执行结果,其中列出了该目录下的所有文件。

e0edb65e779b95ce76a54e50a8b554c3.png

图1  上传漏洞造成的webshell执行结果

2、检查文件类型防止上传漏洞

上面例子中的代码非常简单,并没有进行任何的上传限制。如果要限制,通常的做法是限制文件上传类型。

下面在PHP代码中增加了文件类型限制来防止上传漏洞。

if($_FILES['userfile']['type']!="image/gif") {

die("请上传正确的文件类型");

}

$uploaddir='uploads';

$uploadfile=$uploaddir.basename($_FILES['userfile']['name']);

if(move_uploaded_file($_FILES['userfile']['tmp_name'],$uploadfile)) {

echo "恭喜您,文件上传成功";

} else {

echo "文件上传失败";

}

?>

在这种情况下,如果攻击者试图上传shell.php,则应用程序在上传请求中将检查文件MIME类型。以下是拒绝上传的HTTP请求返回数据包。

POST /upload.php HTTP/1.1

TE: deflate,gzip;q=0.3

Connection: TE,close

Host: localhost:8080

User-Agent: Mozilla/5.0(Macintosh: Inter Mac OS X10_13_2)

AppleWebKit/537.36(KHTML,like gecko) Chrome/65.0.3325.181

Safari/537.36

Content-Type: multipart/form-data;boundary=xYzzY

Content-Length:32

--s76f8a7sf8as9f8a9f80as8df--

Content-Disposition: form-data;name="userfile";filename="shell.php"

Content-Type: text/plain

system($_GET['shell']);

?>

--s76f8a7sf8as9f8a9f80as8df--

HTTP/1.1 200 OK

Date: Thu, 31 May 2019 22:00:01 GMT

Server: Apache

X-Powered-By: PHP/5.6

Content-Length: 30

Connection: close

Content-Type: text/html

请上传正确的文件类型

这里成功地通过检测类型防止了非授权类型文件的上传,服务器拒绝接收文件。

但是如果只进行上传文件类型的检查也是不够的,攻击者通过修改POST数据包中Content-Type:text/plain字段为Content-Type:image/gif,然后发送数据包,即可成功实现恶意脚本的上传。

3、检查文件扩展名称防止上传漏洞

除了检查文件类型外,研发人员最常用的防范方法之一,就是基于白名单或者黑名单,验证所传文件的扩展名称是否符合。以下代码通过黑名单方式对文件类型进行限制。

$blacklist=array(".php","phtml",".php3",".php4"); // 黑名单

$uploaddir='uploads/';

$uploadfile=$uploaddir.basename($_FILES['userfile']['name']);

$item==substr($_FILES['userfile']['name'],-4);

if(in_array($item,$whitelist)) {

die("请上传正确的文件类型");

}

if(move_uploaded_file($_FILES['userfile']['tmp_name'],$uploadfile)) {

echo "恭喜您,文件上传成功";

} else {

echo "上传失败";

}

?>

以下是白名单模式限制文件类型的代码示例。

$whitelist=array(".jpg",".gif","png"); //白名单

$uploaddir='uploads/';

$uploadfile=$uploaddir.basename($_FILES['userfile']['name']);

$item==substr($_FILES['userfile']['name'],-4);

if(!in_array($item,$whitelist)) {

die("请上传正确的文件类型");

}

if(move_uploaded_file($_FILES['userfile']['tmp_name'],$uploadfile)) {

echo "恭喜您,文件上传成功";

} else {

echo "上传文件失败";

}

?>

从黑名单和白名单两种不同的验证方法来看,白名单方式绝对要比黑名单安全得多。但是,并不是说采用白名单方式验证就足够安全了。

IIS服务存在一个漏洞(Microsoft Internet Infomation Server 6.0 ISAPI Filename Analytic Vulnerability),如上传一个名为hacker.php;.gif的文件到服务器,PHP脚本文件因限制最后4个字符,所以本文件是合法的,但是当上传后浏览该文件——http://服务器路径/uploads/hacker.php;.gif时,就可以绕过Web程序的逻辑检查,从而能导致服务器以IIS进程权限执行任意恶意用户定义的脚本。此漏洞只针对于IIS特定版本。

在Apache程序中,同样存在一个由扩展名解析的漏洞。当恶意攻击上传一个有多个扩展名的PHP脚本文件时,如果最后的扩展名未定义,就会解析前一个扩展,比如hacker.php.2018文件。当将该文件上传时,如果是以白名单、黑名单方式进行验证,就可以绕过验证,上传非法文件到服务器,当浏览http://服务器路径/uploads/hacker.php.2018时,就会被当成PHP脚本执行。

4、文件上传漏洞的综合防护

以上例子说明,不可以只通过一种安全手段来阻止攻击者进行非法文件上传,应该同时综合应用检测文件类型、检查文件后缀、黑白名单、使用随机文件名称等多种方法进行防范。下面的代码是综合应用示例。

/**

* 生成随机字符串

* @param int $len

* $return string

*/

function genRandomString($len) {

$chars=array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9");

$charsLen=count($chars)-1;

shuffle($chars); // 将精妙绝伦打乱

$output="";

for($i=0;$i<=$len;$i++) {

$output.=$chars[mt_rand(0,$charsLen)];

}

return $output;

}

$whitelist=array(".jpg",".gif","png"); //白名单

$item==substr($_FILES['userfile']['name'],-4);

if(!in_array($item,$whitelist)) {

die("请上传正确的文件类型");

}

if($_FILES['userfile']['type']!="image/gif") { // 校验文件MIME类型

die("请上传正确的文件类型");

}

$uploaddir='/tmp/uploads'; // 将用户上传的文件放到项目目录之外

$uploadfile=$uploaddir.genRandomString(20).$item; // 使用随机文件名

if(move_uploaded_file($_FILES['userfile']['tmp_name'],$uploadfile)) {

echo "恭喜您,文件上传成功";

} else {

echo "上传文件失败";

}

?>

验证上传文件的扩展名,以白名单、黑名单方式为主,但最好使用白名单。

除了在代码逻辑中防止上传漏洞外,同时也可以在项目部署时将上传目录放到项目工程目录之外,当作静态资源文件处理,并且对文件的权限进行设定,禁止文件的执行权限。

当用户上传文件到服务器保存时,一定要使用随机文件名进行存储,并保证所存储的扩展名合法。保证文件名的唯一性,也保证了存储的安全性,可以防止上传文件非法扩展进行解析。

微信公众号:计算机与网络安全

ID:Computer-network

【推荐书籍】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/305327.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ 入门:2. Exchange 和 Queue

上文RabbitMQ 入门&#xff1a;1. Message Broker&#xff08;消息代理&#xff09;提到过 RabbitMQ 实现了 AMQP 这个协议&#xff08;RabbitMQ 所支持的 AMQP 的版本是 0.9.1&#xff09;&#xff0c;这个协议的内容很多&#xff0c;但为了构建入门级的分布式应用&#xff0c…

【组图】地震前线归来--心中的震撼

5.12号获悉家乡发生大地震&#xff0c;不放心在成都的家人朋友&#xff0c;于13日从北京赶回成都&#xff0c;再了解事态严重性&#xff0c;并确定家人情况后&#xff0c;14日与众多志愿者一起从成都出发&#xff0c;取道彭州市&#xff0c;通济镇&#xff0c;白水河镇&#xf…

mysql数据库密码错误_MySQL数据库经典错误六 数据库密码忘记的问题

数据库密码忘记的问题[rootzs ~]# mysql -uroot -pEnter password:ERROR 1045 (28000): Access denied for user ‘root’’localhost’ (using password: YES)[rootzs ~]# mysql -uroot -pEnter password:ERROR 1045 (28000): Access denied for user ‘root’’localhost’ (…

前端 input怎么显示null_小猿圈WEB前端之HTML5+CSS3面试题(一)

学习是一件非常充实的过程&#xff0c;特别是把自己的乐趣变成工作的时候&#xff0c;很多朋友就喜欢学习web前端&#xff0c;所以学习前端&#xff0c;也希望从事前端的工作&#xff0c;但是因为缺少实战经验&#xff0c;所以很多都是卡在面试这关上&#xff0c;下面小猿圈总结…

使用AXIS开发Web Service的示例

1)先下载Axis的文件包 &#xff1a;http://ws.apache.org/axis/2)新建web工程 名称为&#xff1a;axis 拷贝Axis包中 webapps/axis 目录中的所有文件到工程目录的 webroot 目录中&#xff0c; 然后 刷新 工程 新建一个 java 文件&#xff0c;文件名称为&#xff1a;HelloClient…

聊聊Interlocked.CompareExchange吧?

【导读】私下空余时间一直在研究开源框架&#xff0c;当然也就少不了学习优秀源码&#xff0c;本文也是我查看有关源码时&#xff0c;触碰到我个人知识盲区&#xff0c;做此记录&#xff0c;分享下Interlocked.CompareExchange这玩意用法被讲的很烂了&#xff0c;为何再次被提及…

sae 本地环境 mysql数据库_SAE本地环境与真实环境的差别

其实从刚开始用的时候就发现本地环境和真实环境有不同&#xff0c;导致本地环境我都没怎么用。1、本地环境的php是32bit版本的&#xff0c;真实环境是64bit的。这是我发现的第一个不相同的地方&#xff0c;就是因为这个&#xff0c;直接导致我的应用绝大部分调试工作都是在把代…

winform 统计大量数据重复的元素个数_面试系列:十个海量数据处理方法大总结...

本文将简单总结下一些处理海量数据问题的常见方法。当然这些方法可能并不能完全覆盖所有的问题&#xff0c;但是这样的一些方法也基本可以处理绝大多数遇到的问题。下面的一些问题基本直接来源于公司的面试笔试题目&#xff0c;方法不一定最优&#xff0c;如果你有更好的处理方…

C# 实现一个基于值相等性比较的字典

C# 实现一个基于值相等性比较的字典Intro今天在项目里遇到一个需求&#xff0c;大概是这样的我要比较两个 JSON 字符串是不是相等&#xff0c;JSON 字符串其实是一个 Dictionary<string, string> 但是顺序可能不同&#xff0c;和上一篇 record 使用场景中的第一个需求类似…

RIAMeeting第六次开发者交流活动。

5月的一场大地震带给我们过多的悲痛&#xff0c;但国家还要兴起&#xff0c;技术还要进步&#xff0c;让广大RIA开发者化悲愤为力量&#xff0c;继续开创中国的RIA事业吧&#xff01; 本月的25日&#xff0c;RIAMeeting将举办第六次开发者交流活动&#xff0c;本次活动邀请到了…

java字符串转时间_java字符串和时间转换

import java.text.SimpleDateFormat; import java.util.Date; //将long字符串转换成格式时间输出 public class LongToString {public static void main(String argsp[]){String time="1256006105375"; Date date=new Date(Long.parseLong(time)); SimpleDateFormat …

java 堆栈_Java中线程与堆栈的关系

栈是线程私有的&#xff0c;每个线程都是自己的栈&#xff0c;每个线程中的每个方法在执行的同时会创建一个栈帧用于存局部变量表、操作数栈、动态链接、方法返回地址等信息。每一个方法从调用到执行完毕的过程&#xff0c;就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。其…

巧用lock解决缓存击穿的解决方案

背景缓存击穿是指缓存中没有但数据库中有的数据&#xff08;一般是缓存时间到期&#xff09;&#xff0c;这时由于并发用户特别多&#xff0c;同时读缓存没读到数据&#xff0c;又同时去数据库去取数据&#xff0c;引起数据库压力瞬间增大&#xff0c;造成过大压力。解决方案1、…

ISA禁止了symantec的LiveUpdate的使用

从我们服务器将symantec升级到10.1.5.5000后&#xff0c;就发现ISA客户端的用户&#xff0c;用LiveUpdate没法升级&#xff0c;点击按钮后也会运行升级&#xff0c;但是到最后总是出现一个红色的大叉&#xff0c;说升级失败。这样客户端就只剩下手动用升级包升级或者是通过服务…

java怎么将前端的数据存到关联的表中_Java程序员最可能被考到的14个面试题

1. 如何只扫描一遍就找到位于一个链表正中间的元素&#xff1f; 这是最受欢迎的算法题之一&#xff0c;经常在电话面试中被问到。很多程序员会想&#xff0c;要知道链表的长度&#xff0c;就要先扫描一遍链表&#xff0c;然后在第二遍中取其正中的元素。所以被要求只扫描一遍就…

java 监听文件内容_java 监听文件内容变化

有时候&#xff0c;我们需要确定某些文件是否有变化而做出一些对应的动作&#xff0c;例如&#xff0c;曾经开发的一款服务器中&#xff0c;由于模块比较多&#xff0c;在运行期间有时候需要单独的输出某个模块日志&#xff0c;但又不可能总是开着日志。log4j中已经实现了可以动…

.NET Core 和 .NET Framework 启动可执行文件的差别

在 Windows 下&#xff0c;使用 .NET Framework 构建出来的应用&#xff0c;可以只有一个可执行文件&#xff0c;在可执行文件里面包含了 IL 代码。使用 .NET Core 构建出来的应用&#xff0c;将会包含一个 Exe 可执行文件&#xff0c;和对应的 Dll 文件&#xff0c;而 IL 代码…

firefox 3.0 在 windows 下的编译

&#xff08;1&#xff09;下载firefox 3.0源代码。下载并安装 mozilla-build &#xff08;2&#xff09;运行 start-msvc9.bat&#xff0c;进入shell界面&#xff0c; 查看环境变量&#xff1a; echo $PATH echo $LIB echo $INCLUDE &#xff08;3&#xff09;确保: windo…

常见的几种最优化方法

阅读目录1. 梯度下降法&#xff08;Gradient Descent&#xff09;2. 牛顿法和拟牛顿法&#xff08;Newtons method & Quasi-Newton Methods&#xff09;3. 共轭梯度法&#xff08;Conjugate Gradient&#xff09;4. 启发式优化方法我们每个人都会在我们的生活或者工作中遇到…

安卓平板运行python_使用Python进行手机平板移动开发 | 学步园

过去&#xff0c;Android和iOS上的移动应用程序开发不是Python的强项&#xff0c;但情况可能会发生变化……使用Python进行移动应用开发怎么样&#xff1f;从历史上看&#xff0c;在编写移动GUI应用程序时&#xff0c;Python并没有很强的故事。实际上&#xff0c;仅使用纯Pytho…