PHP 文件上传中的未记录清理
Undocumented sanitization in PHP file upload
根据 PHP official documentation 处理文件上传时,应对文件名进行清理以防止目录遍历和可能的其他类型的攻击:
// basename() may prevent filesystem traversal attacks;
// further validation/sanitation of the filename may be appropriate
$name = basename($_FILES["pictures"]["name"][$key]);
尽管如此,我发现默认情况下,文件名在到达 PHP 脚本时已经被清理。
我有证据表明 Apache 收到了恶意文件名:filename="../file.png",而 PHP 脚本改为在 $_FILES 变量中读取经过净化的名称。
Apache 输入的低级转储:
mod_dumpio: dumpio_in (data-HEAP):
--------------------------eb8b65b665870e02
Content-Disposition: form-data;
name="attachment";
filename="../file.png" ← [Malicious file name]
Content-Type: image/png
PHP 脚本
echo $_FILES['attachment']['name']; ← [File name already sanitised: 'file.png']
我在 Apache 模块和 php-fpm,运行 PHP 从 5.5 到 7.2 都发现了这种行为,我不得不推断 PHP 解释器在将变量传递给脚本之前执行此清理。
所以,感谢 PHP 在我不知情和未经同意的情况下为我做卫生。但是 (这是我的问题) 因为这个功能,据我所知是没有记录的,我想知道清理标准/正则表达式/算法,以确保它满足我的需要.
你想看rfc1867.c
,你指的好像是这个部分:
SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler)
从评论中可以看出,basename() 用于消除伪造的反斜杠,这实际上可能是 正确的(我想也许是“Hello\ World.txt
”?)。 但这是基于 IE 的行为,评论指出将来可能会删除它。
所以你不能依靠这个 "sanitization" 继续呆在那里。
...
/* The \ check should technically be needed for win32 systems only where
* it is a valid path separator. However, IE in all it's wisdom always sends
* the full path of the file on the user's filesystem, which means that unless
* the user does basename() they get a bogus file name. Until IE's user base drops
* to nill or problem is fixed this code must remain enabled for all systems. */
s = _basename(internal_encoding, filename TSRMLS_CC);
if (!s) {
s = filename;
}
根据 PHP official documentation 处理文件上传时,应对文件名进行清理以防止目录遍历和可能的其他类型的攻击:
// basename() may prevent filesystem traversal attacks;
// further validation/sanitation of the filename may be appropriate
$name = basename($_FILES["pictures"]["name"][$key]);
尽管如此,我发现默认情况下,文件名在到达 PHP 脚本时已经被清理。
我有证据表明 Apache 收到了恶意文件名:filename="../file.png",而 PHP 脚本改为在 $_FILES 变量中读取经过净化的名称。
Apache 输入的低级转储:
mod_dumpio: dumpio_in (data-HEAP):
--------------------------eb8b65b665870e02
Content-Disposition: form-data;
name="attachment";
filename="../file.png" ← [Malicious file name]
Content-Type: image/png
PHP 脚本
echo $_FILES['attachment']['name']; ← [File name already sanitised: 'file.png']
我在 Apache 模块和 php-fpm,运行 PHP 从 5.5 到 7.2 都发现了这种行为,我不得不推断 PHP 解释器在将变量传递给脚本之前执行此清理。
所以,感谢 PHP 在我不知情和未经同意的情况下为我做卫生。但是 (这是我的问题) 因为这个功能,据我所知是没有记录的,我想知道清理标准/正则表达式/算法,以确保它满足我的需要.
你想看rfc1867.c
,你指的好像是这个部分:
SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler)
从评论中可以看出,basename() 用于消除伪造的反斜杠,这实际上可能是 正确的(我想也许是“Hello\ World.txt
”?)。 但这是基于 IE 的行为,评论指出将来可能会删除它。
所以你不能依靠这个 "sanitization" 继续呆在那里。
...
/* The \ check should technically be needed for win32 systems only where
* it is a valid path separator. However, IE in all it's wisdom always sends
* the full path of the file on the user's filesystem, which means that unless
* the user does basename() they get a bogus file name. Until IE's user base drops
* to nill or problem is fixed this code must remain enabled for all systems. */
s = _basename(internal_encoding, filename TSRMLS_CC);
if (!s) {
s = filename;
}