When uploading excel on a client's computer, the excel mime-type type is application/octet-stream

Keywords: PHP Excel

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

Reference resources

Ruan Yifeng-mime-type
mime-type
File Upload

Posted by Arrow on Fri, 19 Jul 2019 10:14:46 -0700