29
0
mirror of https://github.com/joomla/joomla-cms.git synced 2024-06-26 07:13:21 +00:00

[3][Security] Correctly allow use of IP headers behind Load Balancers, and Not. (#32866)

Co-authored-by: Richard Fath <richard67@users.noreply.github.com>
Co-authored-by: Brian Teeman <brian@teeman.net>
Co-authored-by: Quy <quy@fluxbb.org>
This commit is contained in:
Phil E. Taylor 2021-04-07 22:31:42 +01:00 committed by GitHub
parent 41566bb93b
commit 21aff1db75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 171 additions and 10 deletions

View File

@ -0,0 +1,90 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_admin
*
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Filesystem\File;
use Joomla\Registry\Registry;
use Joomla\Utilities\ArrayHelper;
/**
* Notifies users of the new Behind Load Balancer option in Global Config, if we detect they might be behind a proxy
*
* @return boolean
*
* @since __DEPLOY_VERSION__
*/
function admin_postinstall_behindproxy_condition()
{
$app = JFactory::getApplication();
if ($app->get('behind_loadbalancer', '0'))
{
return false;
}
if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER) && !empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
return true;
}
if (array_key_exists('HTTP_CLIENT_IP', $_SERVER) && !empty($_SERVER['HTTP_CLIENT_IP']))
{
return true;
}
return false;
}
/**
* Enables the Behind Load Balancer setting in Global Configuration
*
* @return void
*
* @since __DEPLOY_VERSION__
*/
function behindproxy_postinstall_action()
{
$prev = ArrayHelper::fromObject(new JConfig);
$data = array_merge($prev, array('behind_loadbalancer' => '1'));
$config = new Registry($data);
jimport('joomla.filesystem.path');
jimport('joomla.filesystem.file');
// Set the configuration file path.
$file = JPATH_CONFIGURATION . '/configuration.php';
// Get the new FTP credentials.
$ftp = JClientHelper::getCredentials('ftp', true);
// Attempt to make the file writeable if using FTP.
if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0644'))
{
JError::raiseNotice(500, JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTWRITABLE'));
}
// Attempt to write the configuration file as a PHP class named JConfig.
$configuration = $config->toString('PHP', array('class' => 'JConfig', 'closingtag' => false));
if (!File::write($file, $configuration))
{
JFactory::getApplication()->enqueueMessage(JText::_('COM_CONFIG_ERROR_WRITE_FAILED'), 'error');
return;
}
// Attempt to make the file unwriteable if NOT using FTP.
if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0444'))
{
JError::raiseNotice(500, JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE'));
}
}

View File

@ -0,0 +1,3 @@
INSERT INTO `#__postinstall_messages` (`extension_id`, `title_key`, `description_key`, `action_key`, `language_extension`, `language_client_id`, `type`, `version_introduced`, `enabled`, `condition_file`, `condition_method`, `action_file`, `action`)
VALUES
(700, 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_TITLE', 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_DESCRIPTION', 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_ACTION', 'com_admin', 1, 'action', '3.9.26', 1, 'admin://components/com_admin/postinstall/behindproxy.php', 'admin_postinstall_behindproxy_condition', 'admin://components/com_admin/postinstall/behindproxy.php', 'behindproxy_postinstall_action');

View File

@ -0,0 +1,3 @@
INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description_key", "action_key", "language_extension", "language_client_id", "type", "version_introduced", "enabled", "condition_file", "condition_method", "action_file", "action")
VALUES
(700, 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_TITLE', 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_DESCRIPTION', 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_ACTION', 'com_admin', 1, 'action', '3.9.26', 1, 'admin://components/com_admin/postinstall/behindproxy.php', 'admin_postinstall_behindproxy_condition', 'admin://components/com_admin/postinstall/behindproxy.php', 'behindproxy_postinstall_action');

View File

@ -0,0 +1,3 @@
INSERT INTO [#__postinstall_messages] ([extension_id], [title_key], [description_key], [action_key], [language_extension], [language_client_id], [type], [version_introduced], [enabled], [condition_file], [condition_method], [action_file], [action])
VALUES
(700, 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_TITLE', 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_DESCRIPTION', 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_ACTION', 'com_admin', 1, 'action', '3.9.26', 1, 'admin://components/com_admin/postinstall/behindproxy.php', 'admin_postinstall_behindproxy_condition', 'admin://components/com_admin/postinstall/behindproxy.php', 'behindproxy_postinstall_action');

View File

@ -90,6 +90,12 @@ class ConfigModelApplication extends ConfigModelForm
// Merge in the session data.
if (!empty($temp))
{
// $temp can sometimes be an object, and we need it to be an array
if (is_object($temp))
{
$temp = ArrayHelper::fromObject($temp);
}
$data = array_merge($data, $temp);
}

View File

@ -427,6 +427,19 @@
name="proxy"
label="CONFIG_PROXY_SETTINGS_LABEL">
<field
name="behind_loadbalancer"
type="radio"
label="COM_CONFIG_FIELD_LOADBALANCER_ENABLE_LABEL"
description="COM_CONFIG_FIELD_LOADBALANCER_ENABLE_DESC"
class="btn-group btn-group-yesno"
default="0"
filter="integer"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field
name="proxy_enable"
type="radio"

View File

@ -8,6 +8,8 @@
defined('_JEXEC') or die;
use Joomla\Utilities\IpHelper;
// Joomla system checks.
@ini_set('magic_quotes_runtime', 0);
@ -91,11 +93,28 @@ switch ($config->error_reporting)
define('JDEBUG', $config->debug);
unset($config);
// System profiler
if (JDEBUG)
{
// @deprecated 4.0 - The $_PROFILER global will be removed
$_PROFILER = JProfiler::getInstance('Application');
}
/**
* Correctly set the allowing of IP Overrides if behind a trusted proxy/load balancer.
*
* We need to do this as high up the stack as we can, as the default in \Joomla\Utilities\IpHelper is to
* $allowIpOverride = true which is the wrong default for a generic site NOT behind a trusted proxy/load balancer.
*/
if (property_exists($config, 'behind_loadbalancer') && $config->behind_loadbalancer == 1)
{
// If Joomla is configured to be behind a trusted proxy/load balancer, allow HTTP Headers to override the REMOTE_ADDR
IpHelper::setAllowIpOverrides(true);
}
else
{
// We disable the allowing of IP overriding using headers by default.
IpHelper::setAllowIpOverrides(false);
}
unset($config);

View File

@ -136,6 +136,9 @@ COM_ADMIN_PHP_SETTINGS="PHP Settings"
COM_ADMIN_PHP_VERSION="PHP Version"
COM_ADMIN_PHPINFO_DISABLED="The built in phpinfo() function has been disabled by your host."
COM_ADMIN_PLATFORM_VERSION="Joomla! Platform Version"
COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_ACTION="Enable Behind Load Balancer Setting"
COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_DESCRIPTION="<p>For Joomla sites hosted behind Load Balancers and Reverse Proxies a new Global Configuration setting has been introduced with Joomla 3.9.26</p><p>This setting, when enabled, will allow your Load Balancer/Reverse Proxy to provide the real IP address of your visitors. This IP will then be used in your Action Logs and used for tracking voting on articles (if these features are enabled).</p><p><strong>Only sites behind a Load Balance/Reverse Proxy will wish to enable this feature.</strong></p>"
COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_TITLE="New Server Setting \"Behind Load Balancer\""
COM_ADMIN_POSTINSTALL_MSG_HTACCESS_AUTOINDEX_DESCRIPTION="<p>Before 3.9.22 the default htaccess.txt file contained erroneous code meant for disabling directory listings. The security team recommends to manually apply the necessary changes to any existing .htaccess file, as this file can not be updated automatically.</p><p>The old code:</p><pre>&lt;IfModule autoindex&gt;\n IndexIgnore *\n&lt;/IfModule&gt;</pre><p>The new code:</p><pre>&lt;IfModule mod_autoindex.c&gt;\n IndexIgnore *\n&lt;/IfModule&gt;</pre>"
COM_ADMIN_POSTINSTALL_MSG_HTACCESS_AUTOINDEX_TITLE=".htaccess Update Concerning Directory Listings"
COM_ADMIN_REGISTER_GLOBALS="Register Globals"

View File

@ -98,7 +98,7 @@ COM_CONFIG_FRONTEDITING_LABEL="Inline Editing"
COM_CONFIG_FRONTEDITING_MENUSANDMODULES="Modules & Menus"
COM_CONFIG_FRONTEDITING_MENUSANDMODULES_ADMIN_TOO="Modules & Menus (administrator too)"
COM_CONFIG_FRONTEDITING_MODULES="Modules"
COM_CONFIG_FIELD_FORCE_SSL_DESC="Force site access in the selected areas to occur only with HTTPS (encrypted HTTP connections with the https:// protocol prefix) and also force the use of secure cookies. Note, you must have HTTPS enabled on your server to utilise this option."
COM_CONFIG_FIELD_FORCE_SSL_DESC="Force site access in the selected areas to occur only with HTTPS (encrypted HTTP connections with the https:// protocol prefix) and also force the use of secure cookies. Note, you must have HTTPS enabled on your server or load balancer to utilise this option. Enable 'Behind Load Balancer' if your SSL terminates on your load balancer but your site is served on http on its webserver."
COM_CONFIG_FIELD_FORCE_SSL_LABEL="Force HTTPS"
COM_CONFIG_FIELD_FTP_ENABLE_DESC="Enable the built in FTP (File Transfer Protocol) functionality which is needed, in some server environments, instead of the normal upload functionality of Joomla."
COM_CONFIG_FIELD_FTP_ENABLE_LABEL="Enable FTP"
@ -165,6 +165,8 @@ COM_CONFIG_FIELD_REDIS_PERSISTENT_DESC="Persistent Redis."
COM_CONFIG_FIELD_REDIS_PERSISTENT_LABEL="Persistent Redis"
COM_CONFIG_FIELD_REDIS_PORT_DESC="Redis server port."
COM_CONFIG_FIELD_REDIS_PORT_LABEL="Redis Server Port"
COM_CONFIG_FIELD_LOADBALANCER_ENABLE_DESC="If your site is behind a load balancer or reverse proxy, enable this setting so that IP addresses and other configurations within Joomla automatically take this into account."
COM_CONFIG_FIELD_LOADBALANCER_ENABLE_LABEL="Behind Load Balancer"
COM_CONFIG_FIELD_METAAUTHOR_DESC="Show the author meta tag when viewing articles."
COM_CONFIG_FIELD_METAAUTHOR_LABEL="Show Author Meta Tag"
COM_CONFIG_FIELD_METADESC_DESC="Enter a description of the overall website that may be used by search engines. Generally, a maximum of 20 words is best."
@ -180,15 +182,15 @@ COM_CONFIG_FIELD_OFFLINE_IMAGE_LABEL="Offline Image"
COM_CONFIG_FIELD_OFFLINE_MESSAGE_DESC="The custom offline message will be used if the 'Offline Message' field is set to 'Use Custom Message'."
COM_CONFIG_FIELD_OFFLINE_MESSAGE_LABEL="Custom Message"
COM_CONFIG_FIELD_PROXY_ENABLE_DESC="Enable Joomla to use a proxy which is needed in some server environments to fetch URLs like in the Joomla Update component."
COM_CONFIG_FIELD_PROXY_ENABLE_LABEL="Enable Proxy"
COM_CONFIG_FIELD_PROXY_ENABLE_LABEL="Enable Outbound Proxy"
COM_CONFIG_FIELD_PROXY_HOST_DESC="Enter the name of the host of your Proxy server."
COM_CONFIG_FIELD_PROXY_HOST_LABEL="Proxy Host"
COM_CONFIG_FIELD_PROXY_HOST_LABEL="Outbound Proxy Host"
COM_CONFIG_FIELD_PROXY_PASSWORD_DESC="Enter your Proxy password."
COM_CONFIG_FIELD_PROXY_PASSWORD_LABEL="Proxy Password"
COM_CONFIG_FIELD_PROXY_PASSWORD_LABEL="Outbound Proxy Password"
COM_CONFIG_FIELD_PROXY_PORT_DESC="Enter the port that Proxy should be accessed by."
COM_CONFIG_FIELD_PROXY_PORT_LABEL="Proxy Port"
COM_CONFIG_FIELD_PROXY_PORT_LABEL="Outbound Proxy Port"
COM_CONFIG_FIELD_PROXY_USERNAME_DESC="The username used to access the Proxy server."
COM_CONFIG_FIELD_PROXY_USERNAME_LABEL="Proxy Username"
COM_CONFIG_FIELD_PROXY_USERNAME_LABEL="Outbound Proxy Username"
COM_CONFIG_FIELD_SECRET_DESC="This is an auto-generated, unique alphanumeric code for every Joomla installation. It is used for security functions."
COM_CONFIG_FIELD_SECRET_LABEL="Secret"
COM_CONFIG_FIELD_SEF_REWRITE_DESC="Select to use a server's rewrite engine to catch URLs that meet specific conditions and rewrite them as directed. Available for IIS 7 and Apache. <br /><strong>Apache users only!</strong><br />Rename htaccess.txt to .htaccess before activating.<br /><strong>IIS 7 users only!</strong><br />Rename web.config.txt to web.config and install IIS URL Rewrite Module before activating.<br />"

View File

@ -8,6 +8,8 @@
defined('_JEXEC') or die;
use Joomla\Utilities\IpHelper;
// Joomla system checks.
@ini_set('magic_quotes_runtime', 0);
@ -94,11 +96,28 @@ if (!defined('JDEBUG'))
define('JDEBUG', $config->debug);
}
unset($config);
// System profiler
if (JDEBUG)
{
// @deprecated 4.0 - The $_PROFILER global will be removed
$_PROFILER = JProfiler::getInstance('Application');
}
/**
* Correctly set the allowing of IP Overrides if behind a trusted proxy/load balancer.
*
* We need to do this as high up the stack as we can, as the default in \Joomla\Utilities\IpHelper is to
* $allowIpOverride = true which is the wrong default for a generic site NOT behind a trusted proxy/load balancer.
*/
if (property_exists($config, 'behind_loadbalancer') && $config->behind_loadbalancer == 1)
{
// If Joomla is configured to be behind a trusted proxy/load balancer, allow HTTP Headers to override the REMOTE_ADDR
IpHelper::setAllowIpOverrides(true);
}
else
{
// We disable the allowing of IP overriding using headers by default.
IpHelper::setAllowIpOverrides(false);
}
unset($config);