在我们的开发中,经常会遇到接收用户上传的文件,比如我要求用户上传头像是png,jpg,gif格式,在收到图片后会根据图片格式类型做不同的头像切割处理,但个别用户会传一些只更改过文件后缀的非标准图片。(直接将.php更改为.jpg), 程序无法对该类型图片进行切割,切割失败。

请教大家:1、有什么好的方法获取文件后缀名?2、如何准确判断后缀名与文件实际类型相匹配?

1.php自己就能取后缀名啊 http://php.net/manual/en/features.file-upload.php2.http://php.net/manual/en/ref.fileinfo.php 可以判断文件类型

1.mixed pathinfo ( string $path [, int $options ] )2.支持@方汉

不过还是没法防止把PHP代码嵌入在图片中

比如:1.有一个正常的图片a.jpg2.有一个php代码文件:b.php [这里当然也可以其它恶意代码]3.copy /b a.jpg + b.php c.jpg 得到c.jpg

这个c.jpg里既有图片特征也带有PHP的执行代码,碰到NGINX 0day漏洞的话就可以直接在URL里执行里面的PHP内容,所以需要把上传目录设置为只支持静态执行,不支持动态,不支持静态资源接收POST请求。

2010-10-30 17:26:14

10 Answers

下面的方法就可以获取文件真实类型:

<?php $image_file = "test.jpg "; $image_size = getimagesize($image_file); print( "文件的格式为: ". $image_size[2]. " "); ?>

2010-10-30 21:00:13

1.php自己就能取后缀名啊 http://php.net/manual/en/features.file-upload.php
2.http://php.net/manual/en/ref.fileinfo.php 可以判断文件类型

2010-10-30 22:35:29

通过文件名来判断有些是不准确的,最好的方式是通过文件内容来判断,通过文件内容判断有两种方法,一种文件的特征码,另一种是文件格式头,这里我只介绍通过文件格式头来判断的方法,思路来源之前看mplayer的源代码时,发现它是通过解析文件内容来判断,不过这部分代码主要是针对视频文件格式的,后来工作中用到需要准确判断文件格式的功能,就把这部分代码抽离出来,另外在此基础上增加了判断其他一些比较常见的WEB文件格式的代码,这部分功能都已经封装成了类,针对PHP来说可以把这个代码封装成PHP的插件,测试过效率还可以。

//*************************************************************************************** // Description: CWinType 判断文件格式 //**************************************************************************************** /* * 类型描述 * 类型 <hr> "MS Windows special zipped file", * "zip" "Icon for MS Windows", * "ico" "HTML document text", * "htm" "Zip archive data", * "zip" "RAR archive data", * "rar" "PDF document", * "pdf" "Rich Text Format", * "doc" "MPEG sequence", * "mpg" "Microsoft ASF", * "wma" "RealAudio sound file", * "rm" "RealMedia file", * "rm" "RIFF (little-endian) data, AVI", * "avi" "RIFF (little-endian) data, wrapped MPEG-1 (CDXA)", * "dat", "RIFF (little-endian) data, WAVE audio", * "wav" "PNG image data", * "png" "GIF image data", * "gif" "JPEG image data", * "jpg" "MS Windows icon resource", * "ico" "Audio file with ID3", * "mp3" "Macromedia Flash data", * "swf" "Macromedia Flash Video", * "flv" "JPEG 2000 image", * "jpg" "MPEG ADTS, layer", * "mp3" "MPEG ADTS, AAC", * "aac" "JPEG image data", * "jpg" "MS-DOS executable PE", * "exe","dll" "QuickTime", * "mov" "MPEG v4", * "mov" */ //****************************************************************************** #ifndef __WINTYPE_H__ #define __WINTYPE_H__ #include "public.h" class CItem; class CWinType { protected: CWinType(); public: virtual ~CWinType(); public: BOOL Init(); BOOL Unit(); BOOL DelAllItem(); public: wstring GetFileType(const char* pBuf, int nLen); static CWinType* Instance(); static BOOL UnInstance(); protected: BOOL RegsitAllType(); void AddItem(CItem* pItem); private: static CWinType* m_pInstance; list<CItem*> m_List; }; #endif // WinType.cpp: implementation of the CWinType class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "WinType.h" #include "Item.h" CWinType* CWinType::m_pInstance = NULL; CWinType* CWinType::Instance() { if (NULL == m_pInstance) { m_pInstance = new CWinType(); } return m_pInstance; } BOOL CWinType::UnInstance() { if (NULL != m_pInstance) { delete m_pInstance; } m_pInstance = NULL; return TRUE; } CWinType::CWinType() { } CWinType::~CWinType() { Unit(); } BOOL CWinType::Init() { return RegsitAllType(); } BOOL CWinType::Unit() { DelAllItem(); return TRUE; } BOOL CWinType::DelAllItem() { list<CItem*>::iterator iter; CItem* pItem = NULL; for (iter=m_List.begin(); iter!=m_List.end(); ++iter) { pItem = *iter; if (NULL != pItem) { delete pItem; } pItem = NULL; } m_List.clear(); return TRUE; } BOOL CWinType::RegsitAllType() { CItem* pItem = NULL; pItem = new CAacType(); AddItem(pItem); pItem = new CAsfType(); AddItem(pItem); pItem = new CAVIType(); AddItem(pItem); pItem = new CDatType(); AddItem(pItem); pItem = new CFlvType(); AddItem(pItem); pItem = new CMidType(); AddItem(pItem); pItem = new CMovType(); AddItem(pItem); pItem = new CRaType(); AddItem(pItem); pItem = new CRmType(); AddItem(pItem); pItem = new CWavType(); AddItem(pItem); pItem = new CRarType(); AddItem(pItem); pItem = new CZipType(); AddItem(pItem); pItem = new CPdfType(); AddItem(pItem); pItem = new CJpgType(); AddItem(pItem); pItem = new CPngType(); AddItem(pItem); pItem = new CGifType(); AddItem(pItem); pItem = new CHtmType(); AddItem(pItem); pItem = new CSwfType(); AddItem(pItem); pItem = new CExeDllType(); AddItem(pItem); pItem = new CMp3Type(); AddItem(pItem); return TRUE; } void CWinType::AddItem(CItem* pItem) { this->m_List.push_back(pItem); } wstring CWinType::GetFileType(const char* pBuf, int nLen) { list<CItem*>::iterator iter; CItem* pItem = NULL; for (iter=m_List.begin(); iter!=m_List.end(); ++iter) { pItem = *iter; if (NULL != pItem) { if (pItem->GetWinType((char*)pBuf, nLen)) { return pItem->GetTypeDes(); } } pItem = NULL; } return L""; }

2010-10-31 00:10:34

用getimagesize 获取 如果是 图片会获取图片类型 如果不是图片会返回false

2010-10-31 01:53:57

1.简单的用文件扩展名判断
pathinfo(filename,PATHINFO_EXTENSION);
2.读文件
原为 a.jpg 现改为 a.php

$filename = "a.php"; $file = fopen($filename, "rb"); $bin = fread($file, 2); //只读2字节 fclose($file); $strInfo = @unpack("C2chars", $bin); $typeCode = intval($strInfo['chars1'].$strInfo['chars2']); echo $typeCode; //查看对应的编码

2010-10-31 03:34:16

1.mixed pathinfo ( string $path [, int $options ] )
2.支持@方汉

不过还是没法防止把PHP代码嵌入在图片中

比如:
1.有一个正常的图片a.jpg
2.有一个php代码文件:b.php [这里当然也可以其它恶意代码]
3.copy /b a.jpg + b.php c.jpg 得到c.jpg

这个c.jpg里既有图片特征也带有PHP的执行代码,碰到NGINX 0day漏洞的话就可以直接在URL里执行里面的PHP内容,所以需要把上传目录设置为只支持静态执行,不支持动态,不支持静态资源接收POST请求。

2010-10-31 05:02:02
您不能回答该问题或者回答已经关闭!

相关文章推荐

  • C#中using指令的几种用法

    using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的详细命名空间,类似于Java的import,这个功能也是最常用的,几乎每个cs的程序都会用到

  • C#实例解析适配器设计模式

    将一个类的接口变成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够一起工作

  • C#运行时相互关系

    C#运行时相互关系,包括运行时类型、对象、线程栈和托管堆之间的相互关系,静态方法、实例方法和虚方法的区别等等

  • 使用托管C++粘合C#和C++代码(二)

    本文实现一下C++代码调用C#代码的过程。我构造一个简单并且直观的例子:通过C++ UI 触发C# UI.

  • C#开发高性能Log Help类设计开发

    项目中要在操作数据库的异常处理中加入写Log日志,对于商业上有要求,写log时对其它操作尽可能影响小,不能因为加入log导致耗时太多

  • Async和Await使异步编程更简单

    C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作

  • C#开发中的反射机制

    反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等

  • C#协变和逆变

    “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型,“逆变”则是指能够使用派生程度更小的类型

  • C#基础概念之延迟加载

    延迟加载(lazy load)是Hibernate3关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作

  • C#中的索引器的简单理解和用法

    C#中的类成员可以是任意类型,包括数组和集合。当一个类包含了数组和集合成员时,索引器将大大简化对数组或集合成员的存取操作

  • 使用托管C++粘合C#和C++代码(一)

    C#在xml读写,数据库操纵,界面构造等很多方面性能卓越;C++的效率高,是底层开发的必备武器

  • 深入C# 序列化(Serialize)、反序列化(Deserialize)

    C#中的序列化和反序列化,序列化是.NET运行时环境用来支持用户定义类型的流化的机制