Skip to content
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

Unset first node of filename array as we are only checking extension types #2739

Closed
wants to merge 2 commits into from

Conversation

betweenbrain
Copy link
Contributor

Addresses issue #2722

@mbabker
Copy link
Contributor

mbabker commented Dec 30, 2013

IIRC, this check is here for when files get uploaded with file names like malicious.php.txt or something like that. I'd have to dig through the archives known as the tracker and Skype to remember for sure.

@brianteeman
Copy link
Contributor

On 30 Dec 2013 08:07, "Michael Babker" notifications@github.com wrote:

IIRC, this check is here for when files get uploaded with file names like
malicious.php.txt or something like that.

Yes that is the reason. Iirc it is on the security tracker.

I'd have to dig through the archives known as the tracker and Skype to
remember for sure.


Reply to this email directly or view it on GitHub.

@betweenbrain
Copy link
Contributor Author

The problem is that the current code checks every part of a filename, including the name and extension, against the $executable array that contains executable file type extensions. This results in files named something like php.jpg being falsely detected as executable as the file extension array created for the comparison match is currently like:

    Array
    (
        [0] => php <= filename, not extension
        [1] => jpg
    )

My fix is to shift off the first node of the array, which should not be checked, so that the file extension array that is created more accurately looks like:

Array
(
    [1] => jpg
)

With this change, files named like malicious.php.txt are still being correctly checked as the array created to check against is more accurate, like:

Array
(
    [1] => php
    [2] => txt
)

@betweenbrain
Copy link
Contributor Author

@diya5
Copy link

diya5 commented Dec 30, 2013

Seems good. Tested good.

@phproberto
Copy link
Contributor

Shouldn't we just use pathinfo to get the file extension and then check if it's in the forbidden array?

$extension = pathinfo($file['name'], PATHINFO_EXTENSION);

if (in_array($extension, $executable))
{
        $app->enqueueMessage(JText::_('JLIB_MEDIA_ERROR_WARNFILETYPE'), 'notice');

        return false;
}

@betweenbrain
Copy link
Contributor Author

Good question @phproberto

Per http://www.php.net/manual/en/function.pathinfo.php:

Note:
If the path has more than one extension, PATHINFO_EXTENSION returns only the last one and PATHINFO_FILENAME only strips the last one. (see first example below).

In that case, wouldn't malicious.php.txt not be detected as potentially malicious?

@brianteeman
Copy link
Contributor

IIRC PATHINFO_EXTENSION is not enough as it only returns the final extension. The vulnerability that has to be solved is to prevent name.ext.ext being uploaded. This was discussed for a long time on the JSST and there were several options discussed. An alternative to the current method was proposed by @dongilbert at the time

@phproberto
Copy link
Contributor

Ah I see. Then maybe array_diff of file extensions vs executable extensions will save us that foreach.

@ghost
Copy link

ghost commented Dec 31, 2013

There is another mayor flaw in that code. The syntax is wrong!
The > 2 part is inside the count function (both in original code as in this fix):
if (count($explodedFileName > 2))
should be:
if (count($explodedFileName) > 2)

Anyway, I redid the code using an array_intersect instead of a foreach loop:
#2743

Also removed the useless
$format = strtolower(JFile::getExt($file['name']));
as we already have the file name split into parts. So a simple array_pop is sufficient to get the actual extension.

Having said that: shouldn't the upload_extensions and ignore_extensions also be done on all file 'extensions' instead of only on the actual ending extension?
So if you want to ignore jpg, should it allow filenames like image.jpg.txt?

@ghost
Copy link

ghost commented Dec 31, 2013

Also check out: #2744
Fixes the weird html tag check further on in that function.

@ghost ghost mentioned this pull request Dec 31, 2013
@beat
Copy link
Contributor

beat commented Dec 31, 2013

So if you want to ignore jpg, should it allow filenames like image.jpg.txt?

Apache can interpret any extension within a filename with multiple extensions, so it is a security-relevant decision. ;-)

@betweenbrain
Copy link
Contributor Author

should it allow filenames like image.jpg.txt?

In the scope of this PR, the goal is to check for potentially executable files. Given that potentially executable files might be named something like image.php.txt, then yes, I'd block it.

@ghost
Copy link

ghost commented Jan 2, 2014

Well, those are already blocked in the hardcoded checks.

@ghost
Copy link

ghost commented Jan 2, 2014

@betweenbrain So did you take a look at https://github.com/joomla/joomla-cms/pull/2743/files ?
Should be a lot more stable and faster code.

@betweenbrain
Copy link
Contributor Author

From a quick review, yes #2743 does seem like a good solution. My goal here was to just fix the small issue at #2722.

@brianteeman
Copy link
Contributor

This has been superseded by #3973

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants