Skip to content

Commit

Permalink
* Moved all security headers to loadSettings. This one's interesting:…
Browse files Browse the repository at this point in the history
… there was a duplicate X-Frame-Options header being generated by both QueryString and index.php, which is a bad idea generally. (index.php, Load.php, QueryString.php)

* Moved AJAX definition to loadSettings, while I was at it. (Load.php, QueryString.php)

@ Important security note: SSI will no longer go through the X-Frame-Options header, but it's for the best. It's up to the parent script to determine what headers they want to send, generally.
  • Loading branch information
Nao committed Mar 19, 2014
1 parent 1910c57 commit 1015ede
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 42 deletions.
29 changes: 29 additions & 0 deletions core/app/Load.php
Expand Up @@ -35,6 +35,11 @@ function loadSettings()
'app_error_count' => 0,
);

// Is this a page requested through jQuery? If yes, set the AJAX constant so we can choose to show only the template's default block.
$ajax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
define('INFINITE', $ajax && !empty($_POST['infinite']));
define('AJAX', $ajax && !INFINITE);

// Try to load settings from the cache first; they'll never get cached if the setting is off.
if (($settings = cache_get_data('settings', 'forever')) === null)
{
Expand Down Expand Up @@ -271,6 +276,30 @@ function loadSettings()
loadSource('Subs-Scheduled');
ImperativeTask();
}

if (!headers_sent())
{
// Check if compressed output is enabled, supported, and not already being done.
if (!empty($settings['enableCompressedOutput']))
{
// If zlib is being used, turn off output compression.
if (ini_get('zlib.output_compression') >= 1 || ini_get('output_handler') == 'ob_gzhandler')
$settings['enableCompressedOutput'] = 0;
else
{
ob_end_clean();
ob_start('ob_gzhandler');
}
}

// While we're here, clean some outgoing headers, and
// protect against XSS and inclusion in external frames.
header('Server: ');
header('X-Powered-By: ');
header('X-XSS-Protection: 1');
header('X-Frame-Options: SAMEORIGIN');
header('X-Content-Type-Options: nosniff');
}
}

function can_shell_exec()
Expand Down
27 changes: 7 additions & 20 deletions core/app/QueryString.php
Expand Up @@ -19,20 +19,6 @@ function loadPaths()
global $boardurl, $boarddir, $settings, $context;
global $sourcedir, $pluginsdir, $cachedir, $cssdir, $jsdir;

// While we're here cleaning the request, try and clean the headers that we'll send back.
header('X-Powered-By: ');
header('Server: ');
// Additionally, when not in SSI, make sure we don't get included in a frame that we're not in control of.
if (WEDGE != 'SSI')
header('X-Frame-Options: SAMEORIGIN');

define('INVALID_IP', '00000000000000000000000000000000');

// Is this a page requested through jQuery? If yes, set the AJAX constant so we can choose to show only the template's default block.
$ajax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
define('INFINITE', $ajax && !empty($_POST['infinite']));
define('AJAX', $ajax && !INFINITE);

// $scripturl is your board URL if you asked to remove index.php or the user visits for the first time
// (in which case they'll get the annoying PHPSESSID stuff in their URL and we need index.php in them.)
$scripturl = $boardurl . (!empty($settings['pretty_remove_index']) && isset($_COOKIE[session_name()]) ? '/' : '/index.php');
Expand Down Expand Up @@ -132,17 +118,14 @@ function cleanRequest()
{
global $board, $topic, $boardurl, $boarddir, $settings, $context, $action_list;

// What function to use to reverse magic quotes - if sybase is on we assume that the database sensibly has the right unescape function!
$removeMagicQuoteFunction = ini_get('magic_quotes_sybase') || strtolower(ini_get('magic_quotes_sybase')) == 'on' ? 'unescapestring__recursive' : 'stripslashes__recursive';

// Save some memory.. (since we don't use these anyway.)
// These were deprecated years ago. Save some memory.
unset($GLOBALS['HTTP_POST_VARS'], $GLOBALS['HTTP_POST_FILES']);

// These keys shouldn't be set... Ever.
if (isset($_REQUEST['GLOBALS']) || isset($_COOKIE['GLOBALS']))
exit('Invalid request variable.');

// Same goes for numeric keys.
// !! The numeric key exploit was fixed in PHP 5.1, so it needn't be addressed.
foreach (array_merge(array_keys($_POST), array_keys($_GET), array_keys($_FILES)) as $key)
if (is_numeric($key))
exit('Numeric request keys are invalid.');
Expand All @@ -163,6 +146,11 @@ function cleanRequest()
exit;
}

define('INVALID_IP', '00000000000000000000000000000000');

// Determine what function will be used to reverse magic quotes.
$removeMagicQuoteFunction = ini_get('magic_quotes_sybase') || strtolower(ini_get('magic_quotes_sybase')) == 'on' ? 'unescapestring__recursive' : 'stripslashes__recursive';

$supports_semicolon = strpos(ini_get('arg_separator.input'), ';') !== false;

// Are we going to need to parse the ; out?
Expand Down Expand Up @@ -969,4 +957,3 @@ function get_ip_identifier($ip)
);
return wesql::insert_id();
}

22 changes: 0 additions & 22 deletions index.php
Expand Up @@ -82,28 +82,6 @@
// like optimizing or running scheduled tasks.
loadSettings();


if (!headers_sent())
{
// Check if compressed output is enabled, supported, and not already being done.
if (!empty($settings['enableCompressedOutput']))
{
// If zlib is being used, turn off output compression.
if (ini_get('zlib.output_compression') >= 1 || ini_get('output_handler') == 'ob_gzhandler')
$settings['enableCompressedOutput'] = '0';
else
{
ob_end_clean();
ob_start('ob_gzhandler');
}
}

// Basic protection against XSS.
header('X-XSS-Protection: 1');
header('X-Frame-Options: SAMEORIGIN');
header('X-Content-Type-Options: nosniff');
}

// Register an error handler.
set_error_handler('error_handler');

Expand Down

0 comments on commit 1015ede

Please sign in to comment.