Completed
Pull Request — development (#2955)
by Stephen
17:46
created

bootstrap.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * Initialize the ElkArte environment.
5
 *
6
 * @name      ElkArte Forum
7
 * @copyright ElkArte Forum contributors
8
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
9
 *
10
 * This file contains code covered by:
11
 * copyright:	2011 Simple Machines (http://www.simplemachines.org)
12
 * license:		BSD, See included LICENSE.TXT for terms and conditions.
13
 *
14
 * @version 1.1 Release Candidate 1
15
 *
16
 */
17
18
// Bootstrap only once.
19
if (defined('ELKBOOT'))
20
{
21
	return true;
22
}
23
24
$time_start = microtime(true);
25
26
const ELKBOOT = 1;
27
28
// Shortcut for the browser cache stale
29
const CACHE_STALE = '?R11RC1';
30
31
// We're going to want a few globals... these are all set later.
32
global $time_start, $maintenance, $msubject, $mmessage, $mbname, $language;
33
global $boardurl, $webmaster_email, $cookiename;
34
global $db_type, $db_server, $db_name, $db_user, $db_prefix, $db_persist, $db_error_send;
35
global $modSettings, $context, $sc, $user_info, $topic, $board, $txt;
36
global $ssi_db_user, $scripturl, $ssi_db_passwd, $db_passwd;
37
global $boarddir, $sourcedir;
38
39
// Report errors but not depreciated ones
40
$ssi_error_reporting = error_reporting(E_ALL | E_STRICT & ~8192);
41
42
// Directional only script time usage for display
43
// getrusage is missing in php < 7 on Windows
44
if (function_exists('getrusage'))
45
{
46
	$rusage_start = getrusage();
47
}
48
else
49
{
50
	$rusage_start = array();
51
}
52
53
$db_show_debug = false;
54
55
// We don't need no globals. (a bug in "old" versions of PHP)
56 View Code Duplication
foreach (array('db_character_set', 'cachedir') as $variable)
57
{
58
	if (isset($GLOBALS[$variable]))
59
	{
60
		unset($GLOBALS[$variable], $GLOBALS[$variable]);
61
	}
62
}
63
64
// Where the Settings.php file is located
65
$settings_loc = __DIR__ . '/Settings.php';
66
67
// First thing: if the install dir exists, just send anybody there
68
// The ignore_install_dir var is for developers only. Do not add it on production sites
69
if (file_exists('install'))
70
{
71
	if (file_exists($settings_loc))
72
	{
73
		require_once($settings_loc);
74
	}
75
76
	if (empty($ignore_install_dir))
77
	{
78
		if (file_exists($settings_loc) && empty($_SESSION['installing']))
79
		{
80
			$redirec_file = 'upgrade.php';
81
		}
82
		else
83
		{
84
			$redirec_file = 'install.php';
85
		}
86
87
		header('Location: http' . (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) === 'on' ? 's' : '') . '://' . (empty($_SERVER['HTTP_HOST']) ? $_SERVER['SERVER_NAME'] . (empty($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] === '80' ? '' : ':' . $_SERVER['SERVER_PORT']) : $_SERVER['HTTP_HOST']) . (strtr(dirname($_SERVER['PHP_SELF']), '\\', '/') == '/' ? '' : strtr(dirname($_SERVER['PHP_SELF']), '\\', '/')) . '/install/' . $redirec_file);
0 ignored issues
show
Security Response Splitting introduced by
'Location: http' . (!emp...stall/' . $redirec_file can contain request data and is used in response header context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Fetching key HTTP_HOST from $_SERVER
    in bootstrap.php on line 87

Response Splitting Attacks

Allowing an attacker to set a response header, opens your application to response splitting attacks; effectively allowing an attacker to send any response, he would like.

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
88
		die();
89
	}
90
}
91
else
92
{
93
	require_once($settings_loc);
94
}
95
96
// Make sure the paths are correct... at least try to fix them.
97
if (!file_exists($boarddir) && file_exists(__DIR__ . '/agreement.txt'))
98
{
99
	$boarddir = __DIR__;
100
}
101 View Code Duplication
if (!file_exists($sourcedir . '/SiteDispatcher.class.php') && file_exists($boarddir . '/sources'))
102
{
103
	$sourcedir = $boarddir . '/sources';
104
}
105
106
// Check that directories which didn't exist in past releases are initialized.
107 View Code Duplication
if ((empty($cachedir) || !file_exists($cachedir)) && file_exists($boarddir . '/cache'))
108
{
109
	$cachedir = $boarddir . '/cache';
110
}
111
112 View Code Duplication
if ((empty($extdir) || !file_exists($extdir)) && file_exists($sourcedir . '/ext'))
113
{
114
	$extdir = $sourcedir . '/ext';
115
}
116
117 View Code Duplication
if ((empty($languagedir) || !file_exists($languagedir)) && file_exists($boarddir . '/themes/default/languages'))
118
{
119
	$languagedir = $boarddir . '/themes/default/languages';
120
}
121
122
// Time to forget about variables and go with constants!
123
DEFINE('BOARDDIR', $boarddir);
124
DEFINE('CACHEDIR', $cachedir);
125
DEFINE('EXTDIR', $extdir);
126
DEFINE('LANGUAGEDIR', $languagedir);
127
DEFINE('SOURCEDIR', $sourcedir);
128
DEFINE('ADMINDIR', $sourcedir . '/admin');
129
DEFINE('CONTROLLERDIR', $sourcedir . '/controllers');
130
DEFINE('SUBSDIR', $sourcedir . '/subs');
131
DEFINE('ADDONSDIR', $boarddir . '/addons');
132
unset($boarddir, $cachedir, $sourcedir, $languagedir, $extdir);
133
134
// Files we cannot live without.
135
require_once(SOURCEDIR . '/QueryString.php');
136
require_once(SOURCEDIR . '/Session.php');
137
require_once(SOURCEDIR . '/Subs.php');
138
require_once(SOURCEDIR . '/Logging.php');
139
require_once(SOURCEDIR . '/Load.php');
140
require_once(SOURCEDIR . '/Security.php');
141
require_once(SUBSDIR . '/Cache.subs.php');
142
143
// Initialize the class Autoloader
144
require(SOURCEDIR . '/Autoloader.class.php');
145
$autoloder = Elk_Autoloader::getInstance();
146
$autoloder->setupAutoloader(array(SOURCEDIR, SUBSDIR, CONTROLLERDIR, ADMINDIR, ADDONSDIR));
147
$autoloder->register(SOURCEDIR, '\\ElkArte');
148
$autoloder->register(SOURCEDIR . '/subs/BBC', '\\BBC');
149
150
/**
151
 * Set this to one of three values depending on what you want to happen in the case of a fatal error.
152
 *
153
 *  - false: Default, will just load the error sub template and die - not putting any theme layers around it.
154
 *  - true: Will load the error sub template AND put the template layers around it (Not useful if on total custom
155
 * pages).
156
 *  - string: Name of a callback function to call in the event of an error to allow you to define your own methods.
157
 * Will die after function returns.
158
 */
159
$ssi_on_error_method = false;
160
161
// Don't do john didley if the forum's been shut down completely.
162
if ($maintenance == 2 && (!isset($ssi_maintenance_off) || $ssi_maintenance_off !== true))
163
{
164
	die($mmessage);
165
}
166
167
if ($db_show_debug === true && isset($rusage_start))
168
{
169
	Debug::get()->rusage('start', $rusage_start);
170
}
171
172
// Forum in extended maintenance mode? Our trip ends here with a bland message.
173
if (!empty($maintenance) && $maintenance == 2)
174
{
175
	Errors::instance()->display_maintenance_message();
176
}
177
178
// Clean the request.
179
cleanRequest();
180
181
// Initiate the database connection and define some database functions to use.
182
loadDatabase();
183
184
// It's time for settings loaded from the database.
185
reloadSettings();
186
187
// Our good ole' contextual array, which will hold everything
188
if (!isset($context))
189
{
190
	$context = array();
191
}
192
193
// Seed the random generator.
194
elk_seed_generator();
0 ignored issues
show
Deprecated Code introduced by
The function elk_seed_generator() has been deprecated.

This function has been deprecated.

Loading history...
195
196
// Check on any hacking attempts.
197
if (isset($_REQUEST['GLOBALS']) || isset($_COOKIE['GLOBALS']))
198
{
199
	die('No access...');
200
}
201
elseif (isset($_REQUEST['ssi_theme']) && (int) $_REQUEST['ssi_theme'] == (int) $ssi_theme)
202
{
203
	die('No access...');
204
}
205
elseif (isset($_COOKIE['ssi_theme']) && (int) $_COOKIE['ssi_theme'] == (int) $ssi_theme)
206
{
207
	die('No access...');
208
}
209
elseif (isset($_REQUEST['ssi_layers'], $ssi_layers) && (@get_magic_quotes_gpc() ? stripslashes($_REQUEST['ssi_layers']) : $_REQUEST['ssi_layers']) == $ssi_layers)
210
{
211
	die('No access...');
212
}
213
214
if (isset($_REQUEST['context']))
215
{
216
	die('No access...');
217
}
218
219
// Gzip output? (because it must be boolean and true, this can't be hacked.)
220
if (isset($ssi_gzip) && $ssi_gzip === true && detectServer()->outPutCompressionEnabled())
221
{
222
	ob_start('ob_gzhandler');
223
}
224
else
225
{
226
	$modSettings['enableCompressedOutput'] = '0';
227
}
228
229
// Primarily, this is to fix the URLs...
230
ob_start('ob_sessrewrite');
231
232
// Start the session... known to scramble SSI includes in cases...
233
if (!headers_sent())
234
{
235
	loadSession();
236
}
237
else
238
{
239
	if (isset($_COOKIE[session_name()]) || isset($_REQUEST[session_name()]))
240
	{
241
		// Make a stab at it, but ignore the E_WARNINGs generated because we can't send headers.
242
		$temp = error_reporting(error_reporting() & !E_WARNING);
243
		loadSession();
244
		error_reporting($temp);
245
	}
246
247 View Code Duplication
	if (!isset($_SESSION['session_value']))
248
	{
249
		$tokenizer = new Token_Hash();
250
		$_SESSION['session_value'] = $tokenizer->generate_hash(32, session_id());
251
		$_SESSION['session_var'] = substr(preg_replace('~^\d+~', '', $tokenizer->generate_hash(16, session_id())), 0, rand(7, 12));
252
	}
253
254
	$sc = $_SESSION['session_value'];
255
	// This is here only to avoid session errors in PHP7
256
	// microtime effectively forces the replacing of the session in the db each
257
	// time the page is loaded
258
	$_SESSION['mictrotime'] = microtime();
259
}
260
261
// Get rid of $board and $topic... do stuff loadBoard would do.
262
unset($board, $topic);
263
$user_info['is_mod'] = false;
264
$context['user']['is_mod'] = &$user_info['is_mod'];
265
$context['linktree'] = array();
266
267
// Load the user and their cookie, as well as their settings.
268
loadUserSettings();
269
270
// Load the current user's permissions....
271
loadPermissions();
272
273
// Load the current or SSI theme. (just use $ssi_theme = id_theme;)
274
loadTheme(isset($ssi_theme) ? (int) $ssi_theme : 0);
275
276
// Load BadBehavior functions
277
loadBadBehavior();
278
279
// @todo: probably not the best place, but somewhere it should be set...
280
if (!headers_sent())
281
{
282
	header('Content-Type: text/html; charset=UTF-8');
283
}
284
285
// Take care of any banning that needs to be done.
286
if (isset($_REQUEST['ssi_ban']) || (isset($ssi_ban) && $ssi_ban === true))
287
{
288
	is_not_banned();
289
}
290
291
// Do we allow guests in here?
292
if (empty($ssi_guest_access) && empty($modSettings['allow_guestAccess']) && $user_info['is_guest'] && basename($_SERVER['PHP_SELF']) != 'SSI.php')
293
{
294
	$controller = new Auth_Controller();
295
	$controller->action_kickguest();
296
	obExit(null, true);
297
}
298
299
// Load the stuff like the menu bar, etc.
300
if (isset($ssi_layers))
301
{
302
	$template_layers = Template_Layers::getInstance();
303
	$template_layers->removeAll();
304
	foreach ($ssi_layers as $layer)
305
	{
306
		$template_layers->addBegin($layer);
307
	}
308
	template_header();
309
}
310
else
311
{
312
	setupThemeContext();
313
}
314
315
// We need to set up user agent, and make more checks on the request
316
$req = request();
317
318
// Make sure they didn't muss around with the settings... but only if it's not cli.
319
if (isset($_SERVER['REMOTE_ADDR']) && session_id() == '')
320
{
321
	trigger_error($txt['ssi_session_broken'], E_USER_NOTICE);
322
}
323
324
// Without visiting the forum this session variable might not be set on submit.
325
if (!isset($_SESSION['USER_AGENT']) && (!isset($_GET['ssi_function']) || $_GET['ssi_function'] !== 'pollVote'))
326
{
327
	$_SESSION['USER_AGENT'] = $req->user_agent();
328
}
329