Skip to content
Snippets Groups Projects
Commit 6cb3fe2e authored by Seamus Lee's avatar Seamus Lee
Browse files

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 430858da
Branches
Tags
No related merge requests found
......@@ -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);
}
}
......@@ -61,7 +61,8 @@
"psr/simple-cache": "~1.0.1",
"cweagans/composer-patches": "~1.0",
"pear/log": "1.13.1",
"ezyang/htmlpurifier": "4.10"
"ezyang/htmlpurifier": "4.10",
"katzien/php-mime-type": "2.1.0"
},
"scripts": {
"post-install-cmd": [
......
......@@ -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));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment