Skip to content

Instantly share code, notes, and snippets.

@jkalbhenn
Last active November 13, 2018 11:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkalbhenn/f1cacb5a7b80e835b81f6cc49d6e2cc1 to your computer and use it in GitHub Desktop.
Save jkalbhenn/f1cacb5a7b80e835b81f6cc49d6e2cc1 to your computer and use it in GitHub Desktop.
make the nextcloud file access control app (1.4.0) check file content instead of only extensions for mime types
diff -ur nextcloud-orig/apps/files_accesscontrol/lib/Operation.php nextcloud/apps/files_accesscontrol/lib/Operation.php
--- nextcloud-orig/apps/files_accesscontrol/lib/Operation.php 2018-11-12 12:18:56.191652967 +0000
+++ nextcloud/apps/files_accesscontrol/lib/Operation.php 2018-11-13 09:53:04.436715278 +0000
@@ -30,7 +30,7 @@
class Operation implements IOperation{
/** @var IManager */
- protected $manager;
+ protected $manager;
/** @var IL10N */
protected $l;
@@ -47,6 +47,84 @@
$this->l = $l;
}
+ # intera extension begin
+ private function getMimeType($storage, $path) {
+ # adapted from private/Files/Type/Detection.php:detect
+ if (@is_dir($path)) { return "httpd/unix-directory"; }
+ if (function_exists('finfo_open')
+ and function_exists('finfo_file') and $finfo = finfo_open(FILEINFO_MIME)
+ ) {
+ $info = @strtolower(finfo_file($finfo, $path));
+ finfo_close($finfo);
+ if ($info) {
+ $mimeType = strpos($info, ';') !== false ? substr($info, 0, strpos($info, ';')) : $info;
+ return empty($mimeType) ? 'application/octet-stream' : $mimeType;
+ }
+ }
+ $isWrapped = (strpos($path, '://') !== false) and (substr($path, 0, 7) === 'file://');
+ if (!$isWrapped && function_exists("mime_content_type")) {
+ // use mime magic extension if available
+ $mimeType = mime_content_type($path);
+ }
+ if (!$isWrapped && \OC_Helper::canExecute("file")) {
+ // it looks like we have a 'file' command,
+ // lets see if it does have mime support
+ $path = escapeshellarg($path);
+ $fp = popen("file -b --mime-type $path 2>/dev/null", "r");
+ $reply = fgets($fp);
+ pclose($fp);
+ //trim the newline
+ $mimeType = trim($reply);
+ if (empty($mimeType)) {
+ $mimeType = 'application/octet-stream';
+ }
+ }
+ # check that result is a mime type. the various tools used can set it to error strings
+ if (!preg_match("/^[a-zA-Z0-9-]+\/[a-zA-Z0-9-]+$/", $mimeType)) {
+ $mimeType = 'application/octet-stream';
+ }
+ return $mimeType;
+ }
+
+ private function checkMimeType($storage, $path) {
+ # empty array on success, non-empty on failure, as checkFileAccess expects it.
+ # related: for blocking by extension see nextcloud mimetypes management.
+ #debug: file_put_contents("/tmp/nextcloud-mime", $mimeType . "\n", FILE_APPEND);
+ $success = [];
+ $failure = ["mimeType rejected"];
+ # return if file does not exist
+ $path = $storage->getLocalFile($path);
+ if(!file_exists($path)) {
+ return $success;
+ };
+ # get mime type check configurations
+ $operations = $this->manager->getOperations('OCA\FilesAccessControl\Operation');
+ $checks = [];
+ foreach ($operations as $operation) {
+ $checkIds = json_decode($operation['checks'], true);
+ $checks = $this->manager->getChecks($checkIds);
+ }
+ $mimeTypeRegexps = [];
+ foreach ($checks as $a) {
+ if(("OCA\\WorkflowEngine\\Check\\FileMimeType" == $a["class"]) && "matches" == $a["operator"]) {
+ $mimeTypeRegexps[] = $a["value"];
+ }
+ }
+ if(empty($mimeTypeRegexps)) {
+ return $success;
+ }
+ # get the mime type for path
+ $mimeType = $this->getMimeType($storage, $path);
+ # test if the mime type matches any pattern.
+ foreach ($mimeTypeRegexps as $a) {
+ if (preg_match($a, $mimeType)) {
+ return $failure;
+ }
+ }
+ return $success;
+ }
+ # intera extension end
+
/**
* @param IStorage $storage
* @param string $path
@@ -67,6 +145,10 @@
$this->manager->setFileInfo($storage, $filePath);
$match = $this->manager->getMatchingOperations('OCA\FilesAccessControl\Operation');
+ # intera extension begin
+ $match = empty($match) ? $this->checkMimeType($storage, $filePath) : $match;
+ # intera extension end
+
$this->nestingLevel--;
if (!empty($match)) {
@jkalbhenn
Copy link
Author

jkalbhenn commented Nov 13, 2018

apply like patch nextcloud/apps/files_accesscontrol/lib/Operation.php nextcloud-mime-type.patch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment