Php 美元文件[…][';大小';]可以伪造吗?
关于不信任通过PHP中的文件上载发送的MIME类型,有一个众所周知的警告(Php 美元文件[…][';大小';]可以伪造吗?,php,security,file-upload,Php,Security,File Upload,关于不信任通过PHP中的文件上载发送的MIME类型,有一个众所周知的警告($\u FILES[…]['type']),因为它是由HTTP客户端发送的,因此可能是伪造的 文件名($\u FILES[…]['name'])也有类似的警告,它是由HTTP客户端发送的,可能包含潜在的危险字符 但是,我看不到文件大小($\u FILES[…]['size'])是如何伪造的,因为它似乎不是请求负载的一部分,至少我在Chrome的开发工具中看不到它,其中负载看起来像: ------WebKitFormBoun
$\u FILES[…]['type']
),因为它是由HTTP客户端发送的,因此可能是伪造的
文件名($\u FILES[…]['name']
)也有类似的警告,它是由HTTP客户端发送的,可能包含潜在的危险字符
但是,我看不到文件大小($\u FILES[…]['size']
)是如何伪造的,因为它似乎不是请求负载的一部分,至少我在Chrome的开发工具中看不到它,其中负载看起来像:
------WebKitFormBoundarytYAQ3ap4cmAB46Ek
Content-Disposition: form-data; name="picture"; filename="picture.jpg"
Content-Type: image/jpeg
原始文件名和MIME类型按预期显示在这里,但没有大小参数的迹象
尽管如此,我还是偶然发现了Symfony的UploadedFile
实现,它将文件大小视为源于客户端的,因此不可信:
返回文件大小。
它是从上传文件的请求中提取的。则不应将is视为安全值
文件大小是否可以是请求负载的一部分,因此可以伪造,或者它总是从$\u FILES[…]['tmp\u name']
指向的实际文件推断出来,因此总是可信的?请看,简短的回答是,不!这个尺寸不能伪造
唯一不可信的部分是浏览器提供的大小和图像类型
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />
<input type="file" name="pictures" accept="image/png"/>
在这两种情况下,都可能欺骗浏览器,因此必须实现后端解决方案以进一步验证大小和图像类型
还要感谢评论部分的@Andy Gee改进了这个答案
$\u文件[i]['type']由客户端发送,因此不应信任。使用mime_内容_类型($_文件[i]['tmp_名称]])来确保
或者使用我的无耻插件:正如所建议的,我在中检查了PHP源代码
定义[size]
属性所涉及的行包括:
[1042] wlen = write(fd, buff, blen);
...
[1056] total_bytes += wlen;
....
[1242] ZVAL_LONG(&file_size, total_bytes);
...
[1270] snprintf(lbuf, llen, "%s[size]", param);
...
[1275] register_http_post_files_variable_ex(lbuf, &file_size, ...
我将其翻译为:
- 临时文件以
size块写入wlen
- 在每次迭代中,
被添加到wlen
total\u字节中
分配给总字节数
zval文件大小
- 目标变量名
分配给…[size]
lbuf
以file\u size
,lbuf
…[size]
$\u文件[…]['size']
的变量是写入临时文件的实际字节数,该临时文件的路径分配给$\u文件[…]['tmp\u name']
据我所知,没有办法伪造
大小
属性检查PHP源代码,它是实际的缓冲区大小,因此应该是“安全的”可以通过更改发送的文件数据量来伪造。@Dagon您能给我一个相关源代码的链接吗?@Gumbo我不明白您的意思。$\u文件[I]['type']
是由客户端发送的,因此不应被信任。请使用mime\u内容\u类型($\u文件[i]['tmp\u名称])
确认。@AndyGee谢谢,我添加了更多详细信息