-
Notifications
You must be signed in to change notification settings - Fork 175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Security] Amend earlier download fix #2876
Conversation
@driusan Please take a look at this fix when you can. Also, I strongly recommend that we include this function in the
|
I tested this, and I now can see the images again in Imaging browser, and can download (I tested MINC downloads as this is the type of files I usually download). |
@MounaSafiHarab thanks for testing! |
htdocs/mri/jiv/get_file.php
Outdated
} | ||
// resolve path parts (single dot, double dot and double delimiters) | ||
$path = str_replace(array( '/', '\\' ), DIRECTORY_SEPARATOR, $path); | ||
$parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a pretty hard to read way to strip out the empty parts.
Can you just use a function defined inline which returns true if strlen > 0 to make it a little more obvious what the array_filter is trying to filter for, instead of basing it on an implicit assumption that 0 and false are equivalent?
htdocs/mri/jiv/get_file.php
Outdated
continue; | ||
} | ||
if ('..' == $part ) { | ||
array_pop($absolutes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be a good idea to check the return value here and throw an exception if you're trying to pop off of an empty stack.
htdocs/mri/jiv/get_file.php
Outdated
$path = implode(DIRECTORY_SEPARATOR, $absolutes); | ||
// resolve any symlinks | ||
if (file_exists($path) && linkinfo($path) > 0 ) { | ||
$path = readlink($path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this necessary? What's wrong with resolving the path to a symbolic link?
htdocs/mri/jiv/get_file.php
Outdated
@@ -19,6 +19,46 @@ | |||
* @link https://github.com/aces/Loris-Trunk | |||
*/ | |||
|
|||
/** | |||
* This function is to replace PHP's extremely buggy realpath(). | |||
* Taken from https://gist.github.com/umidjons/6154548 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the copyright on it? I don't see any copyright notice, which means it defaults to all rights reserved and we don't have the right to use it unless the author gives explicit written approval.
(Which makes most of my below comments a moot point..)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha... I've messaged the author and if he's feeling generous he'll hopefully license it properly. I'll look into another solution in the meantime.
htdocs/mri/jiv/get_file.php
Outdated
// Check if the resolved 'true' path starts with the prefix. | ||
// If not, user supplied a relative path which is forbidden | ||
if (substr($TruePath, 0, strlen($PathPrefix)) !== $PathPrefix) { | ||
error_log("ERROR: User supplied relative path. Potentially malicious."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might want to include the IP address or username if you're going to provide a message like this, so it can be followed up with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, can do.
htdocs/mri/jiv/get_file.php
Outdated
switch($FileExt) { | ||
case 'mnc': | ||
$FullPath = $mincPath . '/' . $File; | ||
$PathPrefix = $mincPath; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are these all changed instead of just switching realpath to truepath and verifying that it fixes the security issues (and works..)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I did verify it works and fixes the security issue (which has been confirmed by @MounaSafiHarab). You're right this is more of a cosmetic change but it also makes the file a little smaller and I think clearer.
Adding the blocked tag because of the copyright issue. |
@driusan I removed the offending code as well as the cleanup changes. This PR now only contains the minimum changes needed for security. I've tested this on my VM and it allows files to download while also preventing the exploit. |
@driusan do you think you could give me an approving review now that the changes are done? 😂 Also, what are your thoughts on moving this to |
@MounaSafiHarab Would you mind re-testing this with the new changes? |
works for me (tested minc images download in imaging browser)! |
This pull request restores the broken functionality merged in #2868. This fixes the access control issue while allowing valid files to download.
See also: Redmine 12586.