• Page:
  • 1

JFolder::create a better an secure alternative to mkdir

ONLINE

JFolder::create a better an secure alternative to mkdir

1 week, 2 days ago
In uknowva, we take application security very seriously, hence we have patched so many core files. One of them is JFolder class, it has a function called create() which creates a folder, we have now redefined it in such a way that whenever you create a folder an index.html file is by default created in it. This is done to make sure your application is guarded against directory enumeration attacks.

Here is the new function definition for reference:

	/**
	 * Create a folder -- and all necessary parent folders.
	 *
	 * @param   string   $path   A path to create from the base path.
	 * @param   integer  $mode   Directory permissions to set for folders created. 0755 by default.
	 * @param   boolean  $add_index_file if set to yes, then add an index.html file as well in the newly created folder
	 * @return  boolean  True if successful.
	 * @since   11.1
	 */
	public static function create($path = '', $mode = 0755, $add_index_file = true)
	{
		// Initialise variables.
		jimport('joomla.client.helper');
		$FTPOptions = JClientHelper::getCredentials('ftp');
		static $nested = 0;

		// Check to make sure the path valid and clean
		$path = JPath::clean($path);

		// Check if parent dir exists
		$parent = dirname($path);
		if (!self::exists($parent))
		{
			// Prevent infinite loops!
			$nested++;
			if (($nested > 20) || ($parent == $path))
			{
				JError::raiseWarning(
					'SOME_ERROR_CODE',
					__METHOD__ . ': ' . JText::_('JLIB_FILESYSTEM_ERROR_FOLDER_LOOP')
				);
				$nested--;
				return false;
			}

			// Create the parent directory
			if (self::create($parent, $mode) !== true)
			{
				// JFolder::create throws an error
				$nested--;
				return false;
			}

			// OK, parent directory has been created
			$nested--;
		}

		// Check if dir already exists
		if (self::exists($path)) {
			return true;
		}

		// Check for safe mode
		if ($FTPOptions['enabled'] == 1)
		{
			// Connect the FTP client
			jimport('joomla.client.ftp');
			$ftp = JFTP::getInstance(
				$FTPOptions['host'], $FTPOptions['port'], null,
				$FTPOptions['user'], $FTPOptions['pass']
			);

			// Translate path to FTP path
			$path = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $path), '/');
			$ret = $ftp->mkdir($path);
			$ftp->chmod($path, $mode);
		}
		else
		{
			// We need to get and explode the open_basedir paths
			$obd = ini_get('open_basedir');

			// If open_basedir is set we need to get the open_basedir that the path is in
			if ($obd != null)
			{
				if (JPATH_ISWIN) {
					$obdSeparator = ";";
				}
				else {
					$obdSeparator = ":";
				}
				// Create the array of open_basedir paths
				$obdArray = explode($obdSeparator, $obd);
				$inBaseDir = false;
				// Iterate through open_basedir paths looking for a match
				foreach ($obdArray as $test)
				{
					$test = JPath::clean($test);
					if (strpos($path, $test) === 0) {
						$obdpath = $test;
						$inBaseDir = true;
						break;
					}
				}
				if ($inBaseDir == false)
				{
					// Return false for JFolder::create because the path to be created is not in open_basedir
					JError::raiseWarning(
						'SOME_ERROR_CODE',
						__METHOD__ . ': ' . JText::_('JLIB_FILESYSTEM_ERROR_FOLDER_PATH')
					);
					return false;
				}
			}

			// First set umask
			$origmask = @umask(0);

			// Create the path
			if (!$ret = @mkdir($path, $mode))
			{
				@umask($origmask);
				JError::raiseWarning(
					'SOME_ERROR_CODE',
					__METHOD__ . ': ' . JText::_('JLIB_FILESYSTEM_ERROR_COULD_NOT_CREATE_DIRECTORY'),
					'Path: ' . $path
				);
				return false;
			}

			// Reset umask
			@umask($origmask);
		}
		if($ret && $add_index_file)
			file_put_contents($path.DS.'index.html', '');
		
		return $ret;
	}
The following user(s) said Thank You: Rajat Pal, Abhinav Jaiswal, Sagar S Vemul, Aadarsh Jain
  • Page:
  • 1

Upcoming Events

No events found.

Who's Online