Commit af92cb60 authored by Seamus Lee's avatar Seamus Lee

Add whitelist back in and validate extension of file is permtted for the...

Add whitelist back in and validate extension of file is permtted for the mime-type supplied and use mime-type from db if supplied with an fid and eid

Switch to different libary that is php5.6 compatable
parent 0c522e73
......@@ -68,22 +68,22 @@ class CRM_Core_Page_File extends CRM_Core_Page {
$mimeType = '';
$path = CRM_Core_Config::singleton()->customFileUploadDir . $fileName;
}
$passedInMimeType = CRM_Utils_Request::retrieveValue('mime-type', 'String', $mimeType, FALSE);
if (!$path) {
CRM_Core_Error::statusBounce('Could not retrieve the file');
}
if (!empty($mimeType) && !empty($passedInMimeType)) {
if ($passedInMimeType != $mimeType) {
throw new CRM_Core_Exception("Supplied Mime Type does not match file Mime Type");
if (empty($mimeType)) {
$passedInMimeType = CRM_Utils_Request::retrieveValue('mime-type', 'String', $mimeType, FALSE);
if (!in_array($passedInMimeType, explode(',', Civi::settings()->get('requestableMimeTypes')))) {
throw new CRM_Core_Exception("Supplied mime-type is not accepted");
}
}
elseif (!empty($passedInMimeType)) {
$testMimeType = CRM_Utils_File::getMimeType($path);
if ($testMimeType != $passedInMimeType) {
throw new CRM_Core_Exception("Supplied Mime Type does not match file Mime Type");
$extension = CRM_Utils_File::getExtensionFromPath($path);
$candidateExtensions = CRM_Utils_File::getAcceptableExtensionsForMimeType($passedInMimeType);
if (!in_array($extension, $candidateExtensions)) {
throw new CRM_Core_Exception("Supplied mime-type does not match file extension");
}
// Now that we have ensured that the mime-type matches to what we believe is the mime-type of the file
// Now that we have validated mime-type supplied as much as possible lets now set the MimeType variable/
$mimeType = $passedInMimeType;
}
......
......@@ -1067,12 +1067,28 @@ HTACCESS;
}
/**
* Get the Mime-Type of a file based on the url path
* @param string $path full filename path
* @return string|bool
* Get the extensions that this MimeTpe is for
* @param string $mimeType the mime-type we want extensions for
* @return array
*/
public static function getAcceptableExtensionsForMimeType($mimeType = NULL) {
$mapping = \MimeType\Mapping::$types;
$extensions = [];
foreach ($mapping as $extension => $type) {
if ($mimeType == $type) {
$extensions[] = $extension;
}
}
return $extensions;
}
/**
* Get the extension of a file based on its path
* @param string $path path of the file to query
* @return string
*/
public function getMimeType($path = NULL) {
return mime_content_type($path);
public static function getExtensionFromPath($path) {
return pathinfo($path, PATHINFO_EXTENSION);
}
}
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "93a9f686f7eb00fb9d766d262eedb09b",
"content-hash": "2a06373b9174ae3aa2bfb820e2e5a35e",
"packages": [
{
"name": "civicrm/civicrm-cxn-rpc",
......@@ -454,6 +454,50 @@
],
"time": "2017-03-20T17:10:46+00:00"
},
{
"name": "katzien/php-mime-type",
"version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/katzien/PhpMimeType.git",
"reference": "159dfbdcd5906442f3dad89951127f0b9dfa3b78"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/katzien/PhpMimeType/zipball/159dfbdcd5906442f3dad89951127f0b9dfa3b78",
"reference": "159dfbdcd5906442f3dad89951127f0b9dfa3b78",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"phpunit/phpunit": "5.*",
"satooshi/php-coveralls": "1.*"
},
"type": "library",
"autoload": {
"psr-4": {
"MimeType\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Kat Zien"
}
],
"description": "A PHP library to detect the mime type of files.",
"homepage": "https://github.com/katzien/PhpMimeType",
"keywords": [
"mimetype",
"php"
],
"time": "2017-03-23T02:05:33+00:00"
},
{
"name": "marcj/topsort",
"version": "1.1.0",
......
......@@ -1052,4 +1052,18 @@ return [
'help_text' => NULL,
'validate_callback' => 'CRM_Utils_Rule::color',
],
'requestableMimeTypes' => [
'group_name' => 'CiviCRM Preferences',
'group' => 'core',
'name' => 'requestableMimeTypes',
'type' => 'String',
'html_type' => 'Text',
'default' => 'image/jpeg,image/pjpeg,image/gif,image/x-png,image/png,image/jpg,text/html,application/pdf',
'add' => '5.13',
'title' => ts('Mime Types that can be passed as URL params'),
'is_domain' => 1,
'is_contact' => 0,
'description' => ts('Acceptable Mime Types that can be used as part of file urls'),
'help_text' => NULL,
],
];
......@@ -95,4 +95,39 @@ class CRM_Utils_FileTest extends CiviUnitTestCase {
$this->assertEquals($expectedResult, CRM_Utils_File::isValidFileName($fileName));
}
public function pathToFileExtension() {
$cases = [];
$cases[] = ['/evil.pdf', 'pdf'];
$cases[] = ['/helloworld.jpg', 'jpg'];
$cases[] = ['/smartwatch_1736683_1280_9af3657015e8660cc234eb1601da871.jpg', 'jpg'];
return $cases;
}
/**
* Test returning appropriate file extension
* @dataProvider pathToFileExtension
* @param string $path
* @param string $expectedExtension
*/
public function testPathToExtension($path, $expectedExtension) {
$this->assertEquals($expectedExtension, CRM_Utils_File::getExtensionFromPath($path));
}
public function mimeTypeToExtension() {
$cases = [];
$cases[] = ['text/plain', ['txt', 'text', 'conf', 'def', 'list', 'log', 'in']];
$cases[] = ['image/jpeg', ['jpeg','jpg', 'jpe']];
$cases[] = ['image/png', ['png']];
return $cases;
}
/**
* @dataProvider mimeTypeToExtension
* @param stirng $mimeType
* @param array $expectedExtensions
*/
public function testMimeTypeToExtension($mimeType, $expectedExtensions) {
$this->assertEquals($expectedExtensions, CRM_Utils_File::getAcceptableExtensionsForMimeType($mimeType));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment