问题描述
在PHP( $ _ FILES [...] ['type']
)中,通过文件上传发送的MIME类型有一个众所周知的警告,是由HTTP客户端发送的,因此可以伪造。
文件名( $ _ FILES [...] [ 'name']
),它由HTTP客户端发送,可能包含潜在的危险字符。
然而,我看不到可以伪造文件大小( $ _ FILES [...] ['size']
),因为它似乎不是请求有效负载的一部分,至少我在Chrome浏览器中的开发工具中看不到它,有效负载看起来像:
------ WebKitFormBoundarytYAQ3ap4cmAB46Ek
内容处理:表单数据; NAME = 图片;文件名=picture.jpg
内容类型:image / jpeg
和MIME类型在这里是预期的,但没有大小参数的迹象。
不过,我刚刚偶然发现了Symfony的 UploadedFile
的实现,认为文件大小为客户端发起,因此不可信:
$ b
文件大小可以是请求有效载荷的一部分,因此是伪造的,或者它总是从由 $ _ FILES [...] ['tmp_name']
指向的实际文件推断出来的,因此总是值得信任?
正如,我检查了PHP源代码在每次迭代中, wlen
被添加到 total_bytes
TOTAL_BYTES
被分配给 file_size
zval ... [size]
分配给 lbuf
FILE_SIZE在 lbuf
, ... [size]
中包含的名称下注册
li> 所以毫无疑问,唯一分配给 $ _ FILES ['] ['size']
是写入临时文件的实际字节数,其路径分配给 $ _ FILES [...] ['tmp_name']
就我所见,没有办法伪造大小
属性。
There's a well-known caveat about not trusting the MIME type sent via file upload in PHP ($_FILES[...]['type']
) as this is sent by the HTTP client and could therefore be forged.
There's a similar caveat for the file name ($_FILES[...]['name']
), which is sent by the HTTP client and could contain potentially dangerous characters.
However, I can't see how the file size ($_FILES[...]['size']
) could be forged, as it does not seem to be part of the request payload, at least I can't see it in the dev tools in Chrome, where the payload looks like:
------WebKitFormBoundarytYAQ3ap4cmAB46Ek
Content-Disposition: form-data; name="picture"; filename="picture.jpg"
Content-Type: image/jpeg
Original file name and MIME type are here as expected, but no sign of a size parameter.
Still, I've just stumbled upon Symfony's UploadedFile
implementation, that considers the file size as client-originated and therefore not trustable:
Can the file size be part of the request payload, and therefore be forged, or is it always inferred from the actual file pointed to by $_FILES[...]['tmp_name']
, and therefore always trustable?
As suggested by @Dagon in the comments, I checked the PHP source in rfc1867.c.
The lines involved in defining the [size]
attribute are:
[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, ...
Which I translate as:
- 1042 The temp file is written in
wlen
size chunks - 1056 In each iteration,
wlen
is added tototal_bytes
- 1242
total_bytes
is assigned to thefile_size
zval - 1270 The target variable name
...[size]
is assigned tolbuf
- 1275
file_size
is registered under the name contained inlbuf
,...[size]
So without doubt, the only variable ever assigned to $_FILES[...]['size']
is the actual number of bytes written to the temporary file whose path is assigned to $_FILES[...]['tmp_name']
.
As far as I can see, there is no way to forge the size
attribute.
这篇关于$ _FILES ['size']是伪造的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!