关于$_FILES['']['size']与filesize()的安全性及优劣对比问询
PHP中$_FILES['']['size'] vs filesize():差异、优缺点及安全性分析
核心差异
$_FILES['your_file']['size']:来自客户端HTTP请求的Content-Length头,是客户端主动告知的文件大小,PHP在接收文件前就能拿到这个值,完全不需要读取文件内容或访问文件系统。filesize($file_path):PHP主动从服务器文件系统读取已上传文件的实际字节数,是文件在磁盘上的真实大小,必须等文件上传完成后才能调用。
各自优缺点
$_FILES['']['size']
- 优点:
- 性能极高,不需要IO操作,在文件上传初期就能获取,适合快速做初步过滤(比如提前判断是否超过
upload_max_filesize配置)。 - 不需要文件路径,只要文件在上传流程中就能拿到值。
- 性能极高,不需要IO操作,在文件上传初期就能获取,适合快速做初步过滤(比如提前判断是否超过
- 缺点:
- 完全不可信,客户端可以通过篡改HTTP请求头随意修改这个值,比如把100MB的文件标注成1MB。
- 如果上传过程中断(比如网络问题),这个值和服务器上实际保存的不完整文件大小完全不符。
filesize()
- 优点:
- 真实可靠,直接读取文件系统的元数据,能准确反映文件的实际大小,不受客户端篡改影响。
- 可以用于任何已存在的文件,不限于上传的文件。
- 缺点:
- 需要文件已完整上传到服务器,且需要有读取该文件的权限。
- 涉及文件系统IO,性能比
$_FILES['size']略低(但日常场景下差异可以忽略)。 - 对于特殊文件(比如软链接、设备文件)可能返回非预期值,且如果文件在调用
filesize()后被修改,返回的是旧值(PHP会缓存这个结果,需要用clearstatcache()刷新)。
安全性分析
毫无疑问,filesize()更安全,原因如下:
$_FILES['size']是客户端可控的输入,攻击者可以轻松伪造这个值绕过大小校验逻辑。比如后端限制上传最大5MB,攻击者修改Content-Length为4MB,但实际上传一个100MB的恶意脚本,若只依赖$_FILES['size']校验,就会直接放行。filesize()读取的是服务器上文件的真实大小,能确保你拿到的是文件的实际字节数,避免被客户端的虚假信息欺骗。
不过要注意:即使使用filesize(),也不能只靠大小校验保证安全,还要配合文件类型校验(比如用finfo_file()检测MIME类型)、上传目录权限控制、文件名随机化等措施,防止恶意文件上传。
场景推荐
- 初步快速过滤:先用
$_FILES['size']做第一道关卡,比如判断是否超过PHP配置的上传限制,减少后续不必要的处理,但不能作为最终校验依据。 - 最终安全校验:在文件上传完成后,必须调用
filesize()确认真实大小,尤其是当文件需要存储、分发或进一步处理时。
内容的提问来源于stack exchange,提问作者MarcSerra
相关产品推荐
相关产品推荐

