I was not able to find a method inside OJS to block specific files types from being uploaded. OJS has the ability to upload any file type to an article and we kept getting hacked as they were able to upload a .phtml file to the article and then use this file to overwrite the index.php file. I came up with the below solution to stop .phtml files from being uploaded. You can modify this to block any file type or more than one.
From the following file, the lines in red were added to block the .phtml file from being upload. This same script can be used in the future to block other file types if required.
Find the section below and add the lines in red in the same spots or copy and replace the whole function:
/**
* Upload a file.
* @param $fileName string the name of the file used in the POST form
* @param $dest string the path where the file is to be saved
* @return boolean returns true if successful
*/
function uploadFile($fileName, $destFileName) {
$destDir = dirname($destFileName);
// Get the file extension
$name = $_FILES[$fileName]['name'];
$ext = end((explode(".",$name)));
if (!$thisâ>fileExists($destDir, 'dir')) {
// Try to create the destination directory
$thisâ>mkdirtree($destDir);
}
if (!isset($_FILES[$fileName])) return false;
// block phtml files
if ($ext == 'phtml') return false;
// to block more than one file type use if ($ext == 'phtml' || $ext == 'php') return false;
if (move_uploaded_file($_FILES[$fileName]['tmp_name'], $destFileName))
return $thisâ>setMode($destFileName, FILE_MODE_MASK);
return false;
}
I also secured the root public_html to only allow read and execute as there was no need to all writes to the root of this folder.
Note that the only known vector for someone to upload and execute a malicious file is to have your files_dir exposed to the web. This is inherently insecure. If you keep your files_dir outside of your web root (or blocked by your webserverâs access control), malicious actors could still upload such a file, but they wouldnât be able to do anything with it.
If I want to further secure the files_dir directory by removing the x bit on Linux system directory permission (to disallow executable action) would there be any downfall happening to the application such as stopping the legit users from uploading their documents? Or in anyway it will stop the application from functioning normally?
The executable bit in Linux file permissions represents two different things:
For directories, it represents the ability to stat (list the contents of) the directory
For files, it represents the ability to attempt to run the file as code.
For your public_files dir, for users and groups with access, you generally do not want the executable bit set for files, but do want the executable bit set for the directories which contain the files.
Just to add to what @ctgraham said, you can control how OJS sets the permissions on files it creates by working with the umask setting in config.inc.php. But Iâm not sure removing the x bit will have the effect youâre looking for; for example, .php scripts still get executed through the web server regardless of their executable bit state. (Thatâs part of why itâs important to keep the files directory outside of the web root.)
Regards,
Alec Smecher
Public Knowledge Project Team
Thank you @ctgraham and @asmecher , your response helps me understand more the benefit of system file permission restriction ( a precaution ). But the definitive solution is to keep the files directory outside of the web root. A related post here: