problem
mime-type application/octet-stream failed background validation when uploading excel on a client's computer
Interactive process
Users use wps to create files saved in the format mime-type->user uploads excel->browser gets file mime-type and passes Content-Type in the request body:mime-type->obtained by browser passes to server and verifies that the file mime-type->does not pass, returns error to front end
Guess why
1. It is possible that a version of wps saves the mime-type of excel as application/octet-stream or a type not recognized by other browsers by default as application/octet-stream. On our computers, the wps version is newer and the saved file mime-type is application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.
2. When we verify the validity of mime-type in the background, we usually do so:
'application/vnd.ms-excel', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
3. All cannot be passed on the client's computer, but can be passed on our computer
3. While thinkphp5 obtains the uploaded file, it detects that the type of the uploaded file is passed by the browser, which will cause some problems and more serious problems. File Upload Vulnerability
Reference link: MIME
Upload file mime type forgery test
Tools: fiddler
Code:
<?php $allowExcelMimeType = [ 'application/vnd.ms-excel', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', ]; $allowExcelExt = [ 'xls', 'xlsx', ]; $fileInfo = $_FILES['fieldNameHere']; $pos = mb_strripos($fileInfo['name'], '.', 0, 'utf8'); $ext = mb_substr($fileInfo['name'], $pos + 1); $destination = md5(time()) . '.' . $ext; move_uploaded_file($fileInfo['tmp_name'], $destination); var_dump($fileInfo); $mimeType = mime_content_type($destination); echo 'file type:'.$mimeType.PHP_EOL; if (!in_array($ext, $allowExcelExt, true) || !in_array($fileInfo['type'], $allowExcelMimeType, true)) { echo 'Illegal file type:'.$mimeType.PHP_EOL; exit(); } echo 'Upload Successful';
excel normal upload return data:
D:\3_tools\wamp\www\test-some\16.upload.php:22: array (size=5) 'name' => string 'test.xlsx' (length=9) 'type' => string 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' (length=65) 'tmp_name' => string 'D:\3_tools\wamp\tmp\php6F55.tmp' (length=31) 'error' => int 0 'size' => int 17300 //File type: application/octet-stream uploaded successfully
excel file forgery mime-type:
D:\3_tools\wamp\www\test-some\16.upload.php:22: array (size=5) 'name' => string 'test.xlsx' (length=9) 'type' => string 'application/so-cool' (length=19) 'tmp_name' => string 'D:\3_tools\wamp\tmp\php2008.tmp' (length=31) 'error' => int 0 'size' => int 17300 //File type: application/octet-stream Illegal file type: application/octet-stream
Fake php file mime-type, create a php file, change the suffix to xlsx
D:\3_tools\wamp\www\test-some\16.upload.php:22: array (size=5) 'name' => string 'test.php.xlsx' (length=13) 'type' => string 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' (length=65) 'tmp_name' => string 'D:\3_tools\wamp\tmp\php133E.tmp' (length=31) 'error' => int 0 'size' => int 17 //File type: text/x-php uploaded successfully
summary
With this vulnerability, we can skip some file uploads that are not rigorously detected, upload some bad code with the server and execute it
Solution
Function to get the true mime-type of the file in php finfo and mime_content_type
Problems and Expansion
1. Binary Convention for file type (find RFC)
2. How browsers get mimet-type files