Issues (2010)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

wp-admin/setup-config.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
 * Retrieves and creates the wp-config.php file.
4
 *
5
 * The permissions for the base directory must allow for writing files in order
6
 * for the wp-config.php to be created using this page.
7
 *
8
 * @internal This file must be parsable by PHP4.
9
 *
10
 * @package WordPress
11
 * @subpackage Administration
12
 */
13
14
/**
15
 * We are installing.
16
 */
17
define('WP_INSTALLING', true);
18
19
/**
20
 * We are blissfully unaware of anything.
21
 */
22
define('WP_SETUP_CONFIG', true);
23
24
/**
25
 * Disable error reporting
26
 *
27
 * Set this to error_reporting( -1 ) for debugging
28
 */
29
error_reporting(0);
30
31
if ( ! defined( 'ABSPATH' ) ) {
32
	define( 'ABSPATH', dirname( dirname( __FILE__ ) ) . '/' );
33
}
34
35
require( ABSPATH . 'wp-settings.php' );
36
37
/** Load WordPress Administration Upgrade API */
38
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
39
40
/** Load WordPress Translation Install API */
41
require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
42
43
nocache_headers();
44
45
// Support wp-config-sample.php one level up, for the develop repo.
46
if ( file_exists( ABSPATH . 'wp-config-sample.php' ) )
47
	$config_file = file( ABSPATH . 'wp-config-sample.php' );
48
elseif ( file_exists( dirname( ABSPATH ) . '/wp-config-sample.php' ) )
49
	$config_file = file( dirname( ABSPATH ) . '/wp-config-sample.php' );
50
else
51
	wp_die( __( 'Sorry, I need a wp-config-sample.php file to work from. Please re-upload this file to your WordPress installation.' ) );
52
53
// Check if wp-config.php has been created
54
if ( file_exists( ABSPATH . 'wp-config.php' ) )
55
	wp_die( '<p>' . sprintf(
56
			/* translators: %s: install.php */
57
			__( "The file 'wp-config.php' already exists. If you need to reset any of the configuration items in this file, please delete it first. You may try <a href='%s'>installing now</a>." ),
58
			'install.php'
59
		) . '</p>'
60
	);
61
62
// Check if wp-config.php exists above the root directory but is not part of another install
63
if ( @file_exists( ABSPATH . '../wp-config.php' ) && ! @file_exists( ABSPATH . '../wp-settings.php' ) ) {
64
	wp_die( '<p>' . sprintf(
65
			/* translators: %s: install.php */
66
			__( "The file 'wp-config.php' already exists one level above your WordPress installation. If you need to reset any of the configuration items in this file, please delete it first. You may try <a href='%s'>installing now</a>." ),
67
			'install.php'
68
		) . '</p>'
69
	);
70
}
71
72
$step = isset( $_GET['step'] ) ? (int) $_GET['step'] : -1;
73
74
/**
75
 * Display setup wp-config.php file header.
76
 *
77
 * @ignore
78
 * @since 2.3.0
79
 *
80
 * @global string    $wp_local_package
81
 * @global WP_Locale $wp_locale
82
 *
83
 * @param string|array $body_classes
84
 */
85
function setup_config_display_header( $body_classes = array() ) {
86
	$body_classes = (array) $body_classes;
87
	$body_classes[] = 'wp-core-ui';
88
	if ( is_rtl() ) {
89
		$body_classes[] = 'rtl';
90
	}
91
92
	header( 'Content-Type: text/html; charset=utf-8' );
93
?>
94
<!DOCTYPE html>
95
<html xmlns="http://www.w3.org/1999/xhtml"<?php if ( is_rtl() ) echo ' dir="rtl"'; ?>>
96
<head>
97
	<meta name="viewport" content="width=device-width" />
98
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
99
	<meta name="robots" content="noindex,nofollow" />
100
	<title><?php _e( 'WordPress &rsaquo; Setup Configuration File' ); ?></title>
101
	<?php wp_admin_css( 'install', true ); ?>
102
</head>
103
<body class="<?php echo implode( ' ', $body_classes ); ?>">
104
<p id="logo"><a href="<?php esc_attr_e( 'https://wordpress.org/' ); ?>" tabindex="-1"><?php _e( 'WordPress' ); ?></a></p>
105
<?php
106
} // end function setup_config_display_header();
107
108
$language = '';
109 View Code Duplication
if ( ! empty( $_REQUEST['language'] ) ) {
110
	$language = preg_replace( '/[^a-zA-Z_]/', '', $_REQUEST['language'] );
111
} elseif ( isset( $GLOBALS['wp_local_package'] ) ) {
112
	$language = $GLOBALS['wp_local_package'];
113
}
114
115
switch($step) {
116 View Code Duplication
	case -1:
117
		if ( wp_can_install_language_pack() && empty( $language ) && ( $languages = wp_get_available_translations() ) ) {
118
			setup_config_display_header( 'language-chooser' );
119
			echo '<h1 class="screen-reader-text">Select a default language</h1>';
120
			echo '<form id="setup" method="post" action="?step=0">';
121
			wp_install_language_form( $languages );
122
			echo '</form>';
123
			break;
124
		}
125
126
		// Deliberately fall through if we can't reach the translations API.
127
128
	case 0:
129 View Code Duplication
		if ( ! empty( $language ) ) {
130
			$loaded_language = wp_download_language_pack( $language );
131
			if ( $loaded_language ) {
132
				load_default_textdomain( $loaded_language );
0 ignored issues
show
It seems like $loaded_language defined by wp_download_language_pack($language) on line 130 can also be of type boolean; however, load_default_textdomain() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
133
				$GLOBALS['wp_locale'] = new WP_Locale();
134
			}
135
		}
136
137
		setup_config_display_header();
138
		$step_1 = 'setup-config.php?step=1';
139
		if ( isset( $_REQUEST['noapi'] ) ) {
140
			$step_1 .= '&amp;noapi';
141
		}
142
		if ( ! empty( $loaded_language ) ) {
143
			$step_1 .= '&amp;language=' . $loaded_language;
144
		}
145
?>
146
<h1 class="screen-reader-text"><?php _e( 'Before getting started' ) ?></h1>
147
<p><?php _e( 'Welcome to WordPress. Before getting started, we need some information on the database. You will need to know the following items before proceeding.' ) ?></p>
148
<ol>
149
	<li><?php _e( 'Database name' ); ?></li>
150
	<li><?php _e( 'Database username' ); ?></li>
151
	<li><?php _e( 'Database password' ); ?></li>
152
	<li><?php _e( 'Database host' ); ?></li>
153
	<li><?php _e( 'Table prefix (if you want to run more than one WordPress in a single database)' ); ?></li>
154
</ol>
155
<p><?php
156
	/* translators: %s: wp-config.php */
157
	printf( __( 'We&#8217;re going to use this information to create a %s file.' ),
158
		'<code>wp-config.php</code>'
159
	);
160
	?>
161
	<strong><?php
162
		/* translators: 1: wp-config-sample.php, 2: wp-config.php */
163
		printf( __( 'If for any reason this automatic file creation doesn&#8217;t work, don&#8217;t worry. All this does is fill in the database information to a configuration file. You may also simply open %1$s in a text editor, fill in your information, and save it as %2$s.' ),
164
			'<code>wp-config-sample.php</code>',
165
			'<code>wp-config.php</code>'
166
		);
167
	?></strong>
168
	<?php
169
	/* translators: %s: Codex URL */
170
	printf( __( 'Need more help? <a href="%s">We got it</a>.' ),
171
		__( 'https://codex.wordpress.org/Editing_wp-config.php' )
172
	);
173
?></p>
174
<p><?php _e( 'In all likelihood, these items were supplied to you by your Web Host. If you don&#8217;t have this information, then you will need to contact them before you can continue. If you&#8217;re all ready&hellip;' ); ?></p>
175
176
<p class="step"><a href="<?php echo $step_1; ?>" class="button button-large"><?php _e( 'Let&#8217;s go!' ); ?></a></p>
177
<?php
178
	break;
179
180
	case 1:
181
		load_default_textdomain( $language );
182
		$GLOBALS['wp_locale'] = new WP_Locale();
183
184
		setup_config_display_header();
185
	?>
186
<h1 class="screen-reader-text"><?php _e( 'Set up your database connection' ) ?></h1>
187
<form method="post" action="setup-config.php?step=2">
188
	<p><?php _e( 'Below you should enter your database connection details. If you&#8217;re not sure about these, contact your host.' ); ?></p>
189
	<table class="form-table">
190
		<tr>
191
			<th scope="row"><label for="dbname"><?php _e( 'Database Name' ); ?></label></th>
192
			<td><input name="dbname" id="dbname" type="text" size="25" value="wordpress" /></td>
193
			<td><?php _e( 'The name of the database you want to use with WordPress.' ); ?></td>
194
		</tr>
195
		<tr>
196
			<th scope="row"><label for="uname"><?php _e( 'Username' ); ?></label></th>
197
			<td><input name="uname" id="uname" type="text" size="25" value="<?php echo htmlspecialchars( _x( 'username', 'example username' ), ENT_QUOTES ); ?>" /></td>
198
			<td><?php _e( 'Your database username.' ); ?></td>
199
		</tr>
200
		<tr>
201
			<th scope="row"><label for="pwd"><?php _e( 'Password' ); ?></label></th>
202
			<td><input name="pwd" id="pwd" type="text" size="25" value="<?php echo htmlspecialchars( _x( 'password', 'example password' ), ENT_QUOTES ); ?>" autocomplete="off" /></td>
203
			<td><?php _e( 'Your database password.' ); ?></td>
204
		</tr>
205
		<tr>
206
			<th scope="row"><label for="dbhost"><?php _e( 'Database Host' ); ?></label></th>
207
			<td><input name="dbhost" id="dbhost" type="text" size="25" value="localhost" /></td>
208
			<td><?php
209
				/* translators: %s: localhost */
210
				printf( __( 'You should be able to get this info from your web host, if %s doesn&#8217;t work.' ),'<code>localhost</code>' );
211
			?></td>
212
		</tr>
213
		<tr>
214
			<th scope="row"><label for="prefix"><?php _e( 'Table Prefix' ); ?></label></th>
215
			<td><input name="prefix" id="prefix" type="text" value="wp_" size="25" /></td>
216
			<td><?php _e( 'If you want to run multiple WordPress installations in a single database, change this.' ); ?></td>
217
		</tr>
218
	</table>
219
	<?php if ( isset( $_GET['noapi'] ) ) { ?><input name="noapi" type="hidden" value="1" /><?php } ?>
220
	<input type="hidden" name="language" value="<?php echo esc_attr( $language ); ?>" />
221
	<p class="step"><input name="submit" type="submit" value="<?php echo htmlspecialchars( __( 'Submit' ), ENT_QUOTES ); ?>" class="button button-large" /></p>
222
</form>
223
<?php
224
	break;
225
226
	case 2:
227
	load_default_textdomain( $language );
228
	$GLOBALS['wp_locale'] = new WP_Locale();
229
230
	$dbname = trim( wp_unslash( $_POST[ 'dbname' ] ) );
231
	$uname = trim( wp_unslash( $_POST[ 'uname' ] ) );
232
	$pwd = trim( wp_unslash( $_POST[ 'pwd' ] ) );
233
	$dbhost = trim( wp_unslash( $_POST[ 'dbhost' ] ) );
234
	$prefix = trim( wp_unslash( $_POST[ 'prefix' ] ) );
235
236
	$step_1 = 'setup-config.php?step=1';
237
	$install = 'install.php';
238
	if ( isset( $_REQUEST['noapi'] ) ) {
239
		$step_1 .= '&amp;noapi';
240
	}
241
242
	if ( ! empty( $language ) ) {
243
		$step_1 .= '&amp;language=' . $language;
244
		$install .= '?language=' . $language;
245
	} else {
246
		$install .= '?language=en_US';
247
	}
248
249
	$tryagain_link = '</p><p class="step"><a href="' . $step_1 . '" onclick="javascript:history.go(-1);return false;" class="button button-large">' . __( 'Try again' ) . '</a>';
250
251
	if ( empty( $prefix ) )
252
		wp_die( __( '<strong>ERROR</strong>: "Table Prefix" must not be empty.' . $tryagain_link ) );
253
254
	// Validate $prefix: it can only contain letters, numbers and underscores.
255
	if ( preg_match( '|[^a-z0-9_]|i', $prefix ) )
256
		wp_die( __( '<strong>ERROR</strong>: "Table Prefix" can only contain numbers, letters, and underscores.' . $tryagain_link ) );
257
258
	// Test the db connection.
259
	/**#@+
260
	 * @ignore
261
	 */
262
	define('DB_NAME', $dbname);
263
	define('DB_USER', $uname);
264
	define('DB_PASSWORD', $pwd);
265
	define('DB_HOST', $dbhost);
266
	/**#@-*/
267
268
	// Re-construct $wpdb with these new values.
269
	unset( $wpdb );
270
	require_wp_db();
271
272
	/*
273
	 * The wpdb constructor bails when WP_SETUP_CONFIG is set, so we must
274
	 * fire this manually. We'll fail here if the values are no good.
275
	 */
276
	$wpdb->db_connect();
277
278
	if ( ! empty( $wpdb->error ) )
279
		wp_die( $wpdb->error->get_error_message() . $tryagain_link );
280
281
	$wpdb->query( "SELECT $prefix" );
282
	if ( ! $wpdb->last_error ) {
283
		// MySQL was able to parse the prefix as a value, which we don't want. Bail.
284
		wp_die( __( '<strong>ERROR</strong>: "Table Prefix" is invalid.' ) );
285
	}
286
287
	// Generate keys and salts using secure CSPRNG; fallback to API if enabled; further fallback to original wp_generate_password().
288
	try {
289
		$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_ []{}<>~`+=,.;:/?|';
290
		$max = strlen($chars) - 1;
291
		for ( $i = 0; $i < 8; $i++ ) {
292
			$key = '';
293
			for ( $j = 0; $j < 64; $j++ ) {
294
				$key .= substr( $chars, random_int( 0, $max ), 1 );
295
			}
296
			$secret_keys[] = $key;
297
		}
298
	} catch ( Exception $ex ) {
299
		$no_api = isset( $_POST['noapi'] );
300
301
		if ( ! $no_api ) {
302
			$secret_keys = wp_remote_get( 'https://api.wordpress.org/secret-key/1.1/salt/' );
303
		}
304
305
		if ( $no_api || is_wp_error( $secret_keys ) ) {
306
			$secret_keys = array();
307
			for ( $i = 0; $i < 8; $i++ ) {
308
				$secret_keys[] = wp_generate_password( 64, true, true );
309
			}
310
		} else {
311
			$secret_keys = explode( "\n", wp_remote_retrieve_body( $secret_keys ) );
0 ignored issues
show
It seems like $secret_keys can also be of type object<WP_Error>; however, wp_remote_retrieve_body() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
312
			foreach ( $secret_keys as $k => $v ) {
313
				$secret_keys[$k] = substr( $v, 28, 64 );
314
			}
315
		}
316
	}
317
318
	$key = 0;
319
	// Not a PHP5-style by-reference foreach, as this file must be parseable by PHP4.
320
	foreach ( $config_file as $line_num => $line ) {
321
		if ( '$table_prefix  =' == substr( $line, 0, 16 ) ) {
322
			$config_file[ $line_num ] = '$table_prefix  = \'' . addcslashes( $prefix, "\\'" ) . "';\r\n";
323
			continue;
324
		}
325
326
		if ( ! preg_match( '/^define\(\'([A-Z_]+)\',([ ]+)/', $line, $match ) )
327
			continue;
328
329
		$constant = $match[1];
330
		$padding  = $match[2];
331
332
		switch ( $constant ) {
333
			case 'DB_NAME'     :
334
			case 'DB_USER'     :
335
			case 'DB_PASSWORD' :
336
			case 'DB_HOST'     :
337
				$config_file[ $line_num ] = "define('" . $constant . "'," . $padding . "'" . addcslashes( constant( $constant ), "\\'" ) . "');\r\n";
338
				break;
339
			case 'DB_CHARSET'  :
340
				if ( 'utf8mb4' === $wpdb->charset || ( ! $wpdb->charset && $wpdb->has_cap( 'utf8mb4' ) ) ) {
341
					$config_file[ $line_num ] = "define('" . $constant . "'," . $padding . "'utf8mb4');\r\n";
342
				}
343
				break;
344
			case 'AUTH_KEY'         :
345
			case 'SECURE_AUTH_KEY'  :
346
			case 'LOGGED_IN_KEY'    :
347
			case 'NONCE_KEY'        :
348
			case 'AUTH_SALT'        :
349
			case 'SECURE_AUTH_SALT' :
350
			case 'LOGGED_IN_SALT'   :
351
			case 'NONCE_SALT'       :
352
				$config_file[ $line_num ] = "define('" . $constant . "'," . $padding . "'" . $secret_keys[$key++] . "');\r\n";
353
				break;
354
		}
355
	}
356
	unset( $line );
357
358
	if ( ! is_writable(ABSPATH) ) :
359
		setup_config_display_header();
360
?>
361
<p><?php
362
	/* translators: %s: wp-config.php */
363
	printf( __( 'Sorry, but I can&#8217;t write the %s file.' ), '<code>wp-config.php</code>' );
364
?></p>
365
<p><?php
366
	/* translators: %s: wp-config.php */
367
	printf( __( 'You can create the %s manually and paste the following text into it.' ), '<code>wp-config.php</code>' );
368
?></p>
369
<textarea id="wp-config" cols="98" rows="15" class="code" readonly="readonly"><?php
370
		foreach ( $config_file as $line ) {
371
			echo htmlentities($line, ENT_COMPAT, 'UTF-8');
372
		}
373
?></textarea>
374
<p><?php _e( 'After you&#8217;ve done that, click &#8220;Run the install.&#8221;' ); ?></p>
375
<p class="step"><a href="<?php echo $install; ?>" class="button button-large"><?php _e( 'Run the install' ); ?></a></p>
376
<script>
377
(function(){
378
if ( ! /iPad|iPod|iPhone/.test( navigator.userAgent ) ) {
379
	var el = document.getElementById('wp-config');
380
	el.focus();
381
	el.select();
382
}
383
})();
384
</script>
385
<?php
386
	else :
387
		/*
388
		 * If this file doesn't exist, then we are using the wp-config-sample.php
389
		 * file one level up, which is for the develop repo.
390
		 */
391
		if ( file_exists( ABSPATH . 'wp-config-sample.php' ) )
392
			$path_to_wp_config = ABSPATH . 'wp-config.php';
393
		else
394
			$path_to_wp_config = dirname( ABSPATH ) . '/wp-config.php';
395
396
		$handle = fopen( $path_to_wp_config, 'w' );
397
		foreach ( $config_file as $line ) {
398
			fwrite( $handle, $line );
399
		}
400
		fclose( $handle );
401
		chmod( $path_to_wp_config, 0666 );
402
		setup_config_display_header();
403
?>
404
<h1 class="screen-reader-text"><?php _e( 'Successful database connection' ) ?></h1>
405
<p><?php _e( 'All right, sparky! You&#8217;ve made it through this part of the installation. WordPress can now communicate with your database. If you are ready, time now to&hellip;' ); ?></p>
406
407
<p class="step"><a href="<?php echo $install; ?>" class="button button-large"><?php _e( 'Run the install' ); ?></a></p>
408
<?php
409
	endif;
410
	break;
411
}
412
?>
413
<?php wp_print_scripts( 'language-chooser' ); ?>
414
</body>
415
</html>
416