php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #75280 mime_content_type() function bypass
Submitted: 2017-09-29 01:46 UTC Modified: 2017-10-12 21:09 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: larry0 at me dot com Assigned:
Status: Open Package: *Directory/Filesystem functions
PHP Version: 7.0.24 OS: Ubuntu Linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2017-09-29 01:46 UTC] larry0 at me dot com
Description:
------------
 The functions finfo_file() and mime_content_type() could be tricked into allowing PHP code execution if a space was placed after the short code <?.  So if my code (test.php) had a single space after the initial <? It would pass the vulnerable codes mime_content_type() check and return as text/html.  If the space was removed it would be flagged as text/x-php.  The vulnerable code checked the mime type using either mime_content_type() or finfo_file() to either allow or block the upload if the file was determined to be PHP or not.


Test script:
---------------
example.php
<?php
 $tmp_name = '/tmp/test.php';
 echo 'Current PHP version: ' . phpversion();
 $finfo = finfo_open(FILEINFO_MIME);
 echo "\nfinfo_file() results: ";
 $file_type = finfo_file($finfo, $tmp_name);
 finfo_close($finfo);
 echo "$file_type\n";
 $file_type = mime_content_type($tmp_name);
 echo "mime_content_type() results: ";
 echo "$file_type\n";
 $cat = `cat $tmp_name`;
 echo "\n";
 echo urlencode($cat);
 echo "\n";
?>

test.php
<?[singlespace]
echo "test";
?>

$ php example.php
Current PHP version: 7.0.22-0ubuntu0.16.04.1
finfo_file() results: text/plain; charset=us-ascii
mime_content_type() results: text/plain
%3C%3F+%0A%0A%3F%3E%0A

$ vi /tmp/test.php 
test.php
<?[space_removed]
echo "test";
?>
$ php example.php
Current PHP version: 7.0.22-0ubuntu0.16.04.1
finfo_file() results: text/x-php; charset=us-ascii
mime_content_type() results: text/x-php

%3C%3F%0A%0A%3F%3E%0A

Expected result:
----------------
Both types detected should be text/x-php.

Actual result:
--------------
With a space after <? it's text/plain vs no space is text/x-php and can be used to bypass security controls.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-10-10 18:14 UTC] larry0 at me dot com
-Package: Filter related +Package: Scripting Engine problem
 [2017-10-10 18:14 UTC] larry0 at me dot com
I think this was in the wrong category.
 [2017-10-12 13:29 UTC] kalle@php.net
-Package: Scripting Engine problem +Package: *Directory/Filesystem functions
 [2017-10-12 13:29 UTC] kalle@php.net
I think this is the best fitting category, as ext/fileinfo doesn't seems to have a category for some reason
 [2017-10-12 20:48 UTC] stas@php.net
-Type: Security +Type: Bug
 [2017-10-12 20:48 UTC] stas@php.net
Not a security issue. If you're using MIME type guesser to decide whether to execute a file, you're doing it wrong.
 [2017-10-12 21:09 UTC] larry0 at me dot com
ok - Sounds good, I found some code doing this and didn't know why my php shell would work sometimes and not others.  I found out it was there use of this function to determine if the type was php or text.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Mon Aug 19 13:01:27 2019 UTC