CVE-2013-5576: Improper Input Validation (CWE-20)
value: administrator/components/com_media/helpers/media.php in the media manager in Joomla! 2.5.x before 2.5.14 and 3.x before 3.1.5 allows remote authenticated users or remote attackers to bypass intended access restrictions and upload files with dangerous extensions via a filename with a trailing . (dot), as exploited in the wild in August 2013.
CWE description: The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
Published: 2013-10-09T14:54Z
Repository: https://github.com/joomla/joomla-cms
Language: PHP
Files changed: administrator/components/com_media/helpers/media.php, administrator/includes/framework.php, administrator/manifests/files/joomla.xml, build/build.php, includes/framework.php, installation/CHANGELOG, installation/sql/mysql/joomla.sql, installation/sql/postgresql/joomla.sql, installation/sql/sqlazure/joomla.sql, libraries/cms/version/version.php, libraries/joomla/filesystem/file.php
Commit date: 2013-07-31 20:23:46 -0500
Commit message: Prepare 3.1.5 release

Diff: diff --git a/administrator/components/com_media/helpers/media.php b/administrator/components/com_media/helpers/media.php
index ba02a8ab1f..a71f8c3ad8 100644
--- a/administrator/components/com_media/helpers/media.php
+++ b/administrator/components/com_media/helpers/media.php
@@ -64,11 +64,11 @@ abstract class MediaHelper
 
 		$format = strtolower(JFile::getExt($file['name']));
 
 		$allowable = explode(',', $params->get('upload_extensions'));
 		$ignored = explode(',', $params->get('ignore_extensions'));
-		if (!in_array($format, $allowable) && !in_array($format, $ignored))
+		if ($format == '' || $format == false || (!in_array($format, $allowable) && !in_array($format, $ignored)))
 		{
 			$err = 'COM_MEDIA_ERROR_WARNFILETYPE';
 			return false;
 		}
 
diff --git a/administrator/includes/framework.php b/administrator/includes/framework.php
index faa006d305..b3368efd40 100644
--- a/administrator/includes/framework.php
+++ b/administrator/includes/framework.php
@@ -15,11 +15,11 @@ defined('_JEXEC') or die;
 @ini_set('magic_quotes_runtime', 0);
 
 /*
  * Installation check, and check on removal of the install directory.
  */
-if (!file_exists(JPATH_CONFIGURATION.'/configuration.php') || (filesize(JPATH_CONFIGURATION.'/configuration.php') < 10) /*|| file_exists(JPATH_INSTALLATION.'/index.php')*/)
+if (!file_exists(JPATH_CONFIGURATION.'/configuration.php') || (filesize(JPATH_CONFIGURATION.'/configuration.php') < 10) || file_exists(JPATH_INSTALLATION.'/index.php'))
 {
 	header('Location: ../installation/index.php');
 	exit();
 }
 
diff --git a/administrator/manifests/files/joomla.xml b/administrator/manifests/files/joomla.xml
index 226ba89f55..8710bf791c 100644
--- a/administrator/manifests/files/joomla.xml
+++ b/administrator/manifests/files/joomla.xml
@@ -3,13 +3,13 @@
 	<name>files_joomla</name>
 	<author>Joomla! Project</author>
 	<authorEmail>admin@joomla.org</authorEmail>
 	<authorUrl>www.joomla.org</authorUrl>
 	<copyright>(C) 2005 - 2013 Open Source Matters. All rights reserved</copyright>
-	<license>GNU General Public License version 2 or later; see     LICENSE.txt</license>
+	<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
 	<version>3.1.5</version>
-	<creationDate>July 2013</creationDate>
+	<creationDate>August 2013</creationDate>
 	<description>FILES_JOOMLA_XML_DESCRIPTION</description>
 
 	<scriptfile>administrator/components/com_admin/script.php</scriptfile>
 
 	<update> <!-- Runs on update; New in 1.7 -->
diff --git a/build/build.php b/build/build.php
index 80d204aca7..4f2de9e01b 100644
--- a/build/build.php
+++ b/build/build.php
@@ -30,11 +30,11 @@ umask(022);
 // Version is first 2 digits (like '1.7', '2.5', or '3.0')
 $version = '3.1';
 
 // Set release for each build
 // Release is third digit (like '0', '1', or '2')
-$release = '2';
+$release = '5';
 
 // Set path to git binary (e.g., /usr/local/git/bin/git or /urs/bin/git)
 $gitPath = '/usr/bin/git';
 
 // Path to local git repository (parent folder of build folder)
@@ -73,10 +73,11 @@ echo "Create list of changed files from git repository.\n";
 // This allows us to install these files from the Extension Manager.
 // So we add the index file for each top-level directory.
 // Note: If we add new top-level directories or files, be sure to include them here.
 $filesArray = array(
 		"administrator/index.php\n" => true,
+		"bin/index.html\n" => true,
 		"cache/index.html\n" => true,
 		"cli/index.html\n" => true,
 		"components/index.html\n" => true,
 		"images/index.html\n" => true,
 		"includes/index.html\n" => true,
@@ -112,12 +113,13 @@ for($num=$release-1; $num >= 0; $num--) {
 	$files = file('diffdocs/'.$version.'.'.$num);
 
 	// Loop through and add all files except: tests, installation, build, .git, or docs
 	foreach ($files AS $file)
 	{
-		if (substr($file, 2, 5) != 'tests' && substr($file, 2, 12) != 'installation' && substr($file,2,5) != 'build'
-		&& substr($file, 2, 4) != '.git' && substr($file, 2, 4) != 'docs' )
+		if (substr($file, 2, 5) != 'tests' && substr($file, 2, 12) != 'installation' && substr($file, 2, 5) != 'build'
+		&& substr($file, 2, 4) != '.git' && substr($file, 2, 4) != 'docs' && substr($file, 2, 7) != '.travis'
+		&& substr($file, 2, 6) != 'travis' && substr($file, 2, 7) != 'phpunit' && substr($file, -3) != '.md')
 		{
 			// Don't add deleted files to the list
 			if (substr($file, 0, 1) != 'D')
 			{
 				$filesArray[substr($file, 2)] = true;
diff --git a/includes/framework.php b/includes/framework.php
index 649a2dda87..cdb6b21f06 100644
--- a/includes/framework.php
+++ b/includes/framework.php
@@ -16,11 +16,11 @@ defined('_JEXEC') or die;
 
 //
 // Installation check, and check on removal of the install directory.
 //
 
-if (!file_exists(JPATH_CONFIGURATION.'/configuration.php') || (filesize(JPATH_CONFIGURATION.'/configuration.php') < 10) /*|| file_exists(JPATH_INSTALLATION.'/index.php')*/) {
+if (!file_exists(JPATH_CONFIGURATION.'/configuration.php') || (filesize(JPATH_CONFIGURATION.'/configuration.php') < 10) || file_exists(JPATH_INSTALLATION.'/index.php')) {
 
 	if (file_exists(JPATH_INSTALLATION.'/index.php'))
 	{
 		header('Location: '.substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], 'index.php')).'installation/index.php');
 		exit();
diff --git a/installation/CHANGELOG b/installation/CHANGELOG
index 3508a29204..d5fea784ae 100644
--- a/installation/CHANGELOG
+++ b/installation/CHANGELOG
@@ -23,10 +23,12 @@ $ -> Language fix or change
 + -> Addition
 ^ -> Change
 - -> Removed
 ! -> Note
 
+-------------------- 3.1.5 Stable Release [01-Aug-2013] ------------------
+
 31-Jul-2013 Michael Babker
  # [#31620] Some plugins cause blank pages in 3.1.4.  Thanks Don Gilbert
  # [#31607] REGRESSION: Changing the autoload order in a point release.  Thanks Don Gilbert
  # [#31598] Fix for B/C break related to Tag saving using *old* way.  Thanks Thomas Hunziker
 
diff --git a/installation/sql/mysql/joomla.sql b/installation/sql/mysql/joomla.sql
index 6476342710..2ed5332d1e 100644
--- a/installation/sql/mysql/joomla.sql
+++ b/installation/sql/mysql/joomla.sql
@@ -592,11 +592,11 @@ INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder`
 (504, 'hathor', 'template', 'hathor', '', 1, 1, 1, 0, '{"legacy":false,"name":"hathor","type":"template","creationDate":"May 2010","author":"Andrea Tarr","copyright":"Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.","authorEmail":"hathor@tarrconsulting.com","authorUrl":"http:\\/\\/www.tarrconsulting.com","version":"1.6.0","description":"TPL_HATHOR_XML_DESCRIPTION","group":""}', '{"showSiteName":"0","colourChoice":"0","boldText":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0),
 (506, 'protostar', 'template', 'protostar', '', 0, 1, 1, 0, '{"name":"protostar","type":"template","creationDate":"4\\/30\\/2012","author":"Kyle Ledbetter","copyright":"Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"","version":"1.0","description":"TPL_PROTOSTAR_XML_DESCRIPTION","group":""}', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0),
 (507, 'isis', 'template', 'isis', '', 1, 1, 1, 0, '{"name":"isis","type":"template","creationDate":"3\\/30\\/2012","author":"Kyle Ledbetter","copyright":"Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"","version":"1.0","description":"TPL_ISIS_XML_DESCRIPTION","group":""}', '{"templateColor":"","logoFile":""}', '', '', 0, '0000-00-00 00:00:00', 0, 0),
 (600, 'English (United Kingdom)', 'language', 'en-GB', '', 0, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0),
 (601, 'English (United Kingdom)', 'language', 'en-GB', '', 1, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0),
-(700, 'Joomla! CMS', 'file', 'joomla', '', 0, 1, 1, 1, '{"legacy":false,"name":"files_joomla","type":"file","creationDate":"July 2013","author":"Joomla!","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.3","description":"FILES_JOOMLA_XML_DESCRIPTION","group":""}', '', '', '', 0, '0000-00-00 00:00:00', 0, 0);
+(700, 'Joomla! CMS', 'file', 'joomla', '', 0, 1, 1, 1, '{"legacy":false,"name":"files_joomla","type":"file","creationDate":"August 2013","author":"Joomla!","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.5","description":"FILES_JOOMLA_XML_DESCRIPTION","group":""}', '', '', '', 0, '0000-00-00 00:00:00', 0, 0);
 
 -- --------------------------------------------------------
 
 --
 -- Table structure for table `#__finder_filters`
diff --git a/installation/sql/postgresql/joomla.sql b/installation/sql/postgresql/joomla.sql
index 4e54a17fbe..6bd7471703 100644
--- a/installation/sql/postgresql/joomla.sql
+++ b/installation/sql/postgresql/joomla.sql
@@ -637,11 +637,11 @@ INSERT INTO "#__extensions" ("extension_id", "name", "type", "element", "folder"
 (600, 'English (United Kingdom)', 'language', 'en-GB', '', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0),
 (601, 'English (United Kingdom)', 'language', 'en-GB', '', 1, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0);
 
 -- Files Extensions
 INSERT INTO "#__extensions" ("extension_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES
-(700, 'Joomla! CMS', 'file', 'joomla', '', 0, 1, 1, 1, '{"legacy":false,"name":"files_joomla","type":"file","creationDate":"July 2013","author":"Joomla!","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.3","description":"FILES_JOOMLA_XML_DESCRIPTION","group":""}', '', '', '', 0, '1970-01-01 00:00:00', 0, 0);
+(700, 'Joomla! CMS', 'file', 'joomla', '', 0, 1, 1, 1, '{"legacy":false,"name":"files_joomla","type":"file","creationDate":"August 2013","author":"Joomla!","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.5","description":"FILES_JOOMLA_XML_DESCRIPTION","group":""}', '', '', '', 0, '1970-01-01 00:00:00', 0, 0);
 
 SELECT nextval('#__extensions_extension_id_seq');
 SELECT setval('#__extensions_extension_id_seq', 10000, false);
 
 --
diff --git a/installation/sql/sqlazure/joomla.sql b/installation/sql/sqlazure/joomla.sql
index ce54adec44..968581ee2d 100644
--- a/installation/sql/sqlazure/joomla.sql
+++ b/installation/sql/sqlazure/joomla.sql
@@ -988,11 +988,11 @@ INSERT INTO #__extensions (extension_id, name, type, element, folder, client_id,
 SELECT 600, 'English (United Kingdom)', 'language', 'en-GB', '', 0, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0
 UNION ALL
 SELECT 601, 'English (United Kingdom)', 'language', 'en-GB', '', 1, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0;
 
 INSERT INTO #__extensions (extension_id, name, type, element, folder, client_id, enabled, access, protected, manifest_cache, params, custom_data, system_data, checked_out, checked_out_time, ordering, state)
-VALUES (700, 'Joomla! CMS', 'file', 'joomla', '', 0, 1, 1, 1, '{"name":"files_joomla","type":"file","creationDate":"July 2013","author":"Joomla!","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.3","description":"FILES_JOOMLA_XML_DESCRIPTION","group":""}', '', '', '', 0, '1900-01-01 00:00:00', 0, 0);
+VALUES (700, 'Joomla! CMS', 'file', 'joomla', '', 0, 1, 1, 1, '{"name":"files_joomla","type":"file","creationDate":"August 2013","author":"Joomla!","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.5","description":"FILES_JOOMLA_XML_DESCRIPTION","group":""}', '', '', '', 0, '1900-01-01 00:00:00', 0, 0);
 
 SET IDENTITY_INSERT #__extensions  OFF;
 
 /****** Object:  Table [#__finder_filters] ******/
 SET QUOTED_IDENTIFIER ON;
diff --git a/libraries/cms/version/version.php b/libraries/cms/version/version.php
index d8bfe81937..93dc1d9ce2 100644
--- a/libraries/cms/version/version.php
+++ b/libraries/cms/version/version.php
@@ -35,11 +35,11 @@ final class JVersion
 
 	/** @var  string  Code name. */
 	public $CODENAME = 'Ember';
 
 	/** @var  string  Release date. */
-	public $RELDATE = '26-July-2013';
+	public $RELDATE = '01-August-2013';
 
 	/** @var  string  Release time. */
 	public $RELTIME = '14:00';
 
 	/** @var  string  Release timezone. */
diff --git a/libraries/joomla/filesystem/file.php b/libraries/joomla/filesystem/file.php
index 8763285b5d..28e2455296 100644
--- a/libraries/joomla/filesystem/file.php
+++ b/libraries/joomla/filesystem/file.php
@@ -59,10 +59,13 @@ class JFile
 	 *
 	 * @since   11.1
 	 */
 	public static function makeSafe($file)
 	{
+		// Remove any trailing dots, as those aren't ever valid file names.
+		$file = rtrim($file, '.');
+
 		$regex = array('#(\.){2,}#', '#[^A-Za-z0-9\.\_\- ]#', '#^\.#');
 
 		return preg_replace($regex, '', $file);
 	}
 

Vulnerable code: 		if (!in_array($format, $allowable) && !in_array($format, $ignored))
if (!file_exists(JPATH_CONFIGURATION.'/configuration.php') || (filesize(JPATH_CONFIGURATION.'/configuration.php') < 10) /*|| file_exists(JPATH_INSTALLATION.'/index.php')*/)
	<license>GNU General Public License version 2 or later; see     LICENSE.txt</license>
	<creationDate>July 2013</creationDate>
$release = '2';
		if (substr($file, 2, 5) != 'tests' && substr($file, 2, 12) != 'installation' && substr($file,2,5) != 'build'
		&& substr($file, 2, 4) != '.git' && substr($file, 2, 4) != 'docs' )
if (!file_exists(JPATH_CONFIGURATION.'/configuration.php') || (filesize(JPATH_CONFIGURATION.'/configuration.php') < 10) /*|| file_exists(JPATH_INSTALLATION.'/index.php')*/) {
(700, 'Joomla! CMS', 'file', 'joomla', '', 0, 1, 1, 1, '{"legacy":false,"name":"files_joomla","type":"file","creationDate":"July 2013","author":"Joomla!","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.3","description":"FILES_JOOMLA_XML_DESCRIPTION","group":""}', '', '', '', 0, '0000-00-00 00:00:00', 0, 0);
(700, 'Joomla! CMS', 'file', 'joomla', '', 0, 1, 1, 1, '{"legacy":false,"name":"files_joomla","type":"file","creationDate":"July 2013","author":"Joomla!","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.3","description":"FILES_JOOMLA_XML_DESCRIPTION","group":""}', '', '', '', 0, '1970-01-01 00:00:00', 0, 0);
VALUES (700, 'Joomla! CMS', 'file', 'joomla', '', 0, 1, 1, 1, '{"name":"files_joomla","type":"file","creationDate":"July 2013","author":"Joomla!","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.3","description":"FILES_JOOMLA_XML_DESCRIPTION","group":""}', '', '', '', 0, '1900-01-01 00:00:00', 0, 0);
	public $RELDATE = '26-July-2013';
Fixed code: 		if ($format == '' || $format == false || (!in_array($format, $allowable) && !in_array($format, $ignored)))
if (!file_exists(JPATH_CONFIGURATION.'/configuration.php') || (filesize(JPATH_CONFIGURATION.'/configuration.php') < 10) || file_exists(JPATH_INSTALLATION.'/index.php'))
	<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
	<creationDate>August 2013</creationDate>
$release = '5';
		"bin/index.html\n" => true,
		if (substr($file, 2, 5) != 'tests' && substr($file, 2, 12) != 'installation' && substr($file, 2, 5) != 'build'
		&& substr($file, 2, 4) != '.git' && substr($file, 2, 4) != 'docs' && substr($file, 2, 7) != '.travis'
		&& substr($file, 2, 6) != 'travis' && substr($file, 2, 7) != 'phpunit' && substr($file, -3) != '.md')
if (!file_exists(JPATH_CONFIGURATION.'/configuration.php') || (filesize(JPATH_CONFIGURATION.'/configuration.php') < 10) || file_exists(JPATH_INSTALLATION.'/index.php')) {
-------------------- 3.1.5 Stable Release [01-Aug-2013] ------------------

(700, 'Joomla! CMS', 'file', 'joomla', '', 0, 1, 1, 1, '{"legacy":false,"name":"files_joomla","type":"file","creationDate":"August 2013","author":"Joomla!","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.5","description":"FILES_JOOMLA_XML_DESCRIPTION","group":""}', '', '', '', 0, '0000-00-00 00:00:00', 0, 0);
(700, 'Joomla! CMS', 'file', 'joomla', '', 0, 1, 1, 1, '{"legacy":false,"name":"files_joomla","type":"file","creationDate":"August 2013","author":"Joomla!","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.5","description":"FILES_JOOMLA_XML_DESCRIPTION","group":""}', '', '', '', 0, '1970-01-01 00:00:00', 0, 0);
VALUES (700, 'Joomla! CMS', 'file', 'joomla', '', 0, 1, 1, 1, '{"name":"files_joomla","type":"file","creationDate":"August 2013","author":"Joomla!","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.5","description":"FILES_JOOMLA_XML_DESCRIPTION","group":""}', '', '', '', 0, '1900-01-01 00:00:00', 0, 0);
	public $RELDATE = '01-August-2013';
		// Remove any trailing dots, as those aren't ever valid file names.
		$file = rtrim($file, '.');