Hardening

wp-config.php: the security settings that really matter

wp-config.php, the security settings that matter

The wp-config.php file holds your database credentials and the secrets that sign your sessions. A few constants in it significantly harden a WordPress site; others, when misunderstood, quietly turn protections off. Here is what each setting really does, checked against the current WordPress source code, and the recommended configuration for production.

Keys and salts: what they are really for

The template file wp-config-sample.php defines eight constants: AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY and their four matching salts. They are used to sign WordPress login cookies and security tokens (nonces). An attacker who knows them can forge valid cookies, so a site that keeps the sample values is seriously exposed.

Two common misconceptions need correcting:

  • they are not used to hash user passwords. Since WordPress 6.8, passwords are hashed with bcrypt, independently of these constants;
  • changing them logs everyone out: the comment in the template file says so, all sessions become invalid.

Generate them with the official service https://api.wordpress.org/secret-key/1.1/salt/, which returns eight lines ready to paste.

Should you rotate them regularly?

No, not without a reason. The WordPress hardening documentation itself links to a technical analysis titled "why you should not rotate your salts." Its argument: many plugins use these values to encrypt data, such as two-factor authentication secrets or API keys. Changing them makes that data unreadable. Change them when they may have leaked: a hacked site, an exposed backup, a file published by mistake, a former contractor.

Turning off the file editor: DISALLOW_FILE_EDIT

By default, an administrator can edit the PHP code of themes and plugins from the Dashboard. If an administrator account is stolen, the editor becomes a direct way to inject code.

define( 'DISALLOW_FILE_EDIT', true );

According to the WordPress hardening guide, this line amounts to removing the edit_themes, edit_plugins and edit_files capabilities. The same guide spells out its limits: it does not stop an attacker from uploading malicious files by other means. It is a measure with no side effects for almost every site, and you should apply it as a matter of course.

DISALLOW_FILE_MODS: stronger, and riskier

DISALLOW_FILE_MODS goes further: it also blocks installing and updating plugins and themes from the Dashboard. But the WordPress code reveals a lesser-known effect: the wp_is_file_mod_allowed() function returns false for every context, including the automatic updates routine. With this constant, minor core security updates no longer install themselves.

Reserve it for sites whose updates are deployed by other means (Git, a deployment tool, the host), with a process that actually keeps up with fixes.

FORCE_SSL_ADMIN: often already on

FORCE_SSL_ADMIN enforces HTTPS for login and the admin area, so passwords and cookies never travel in clear text. The default-constants.php file shows that if you do not define it, WordPress automatically sets it to true when the site address starts with https. Defining it explicitly is still useful to document the choice, or when the stored address is still http. The old FORCE_SSL_LOGIN constant has been deprecated since WordPress 4.0.

WP_DEBUG in production

Debugging is essential in development and dangerous in production, for two reasons.

  • Displaying errors (WP_DEBUG_DISPLAY, true by default when WP_DEBUG is on) reveals file paths, queries and plugin names to any visitor.
  • The log (WP_DEBUG_LOG set to true) is written by default to wp-content/debug.log, an address every bot knows. It can contain sensitive data: in 2024, a LiteSpeed Cache flaw (CVE-2024-44000) relied precisely on session cookies written to this file.

In production, keep WP_DEBUG set to false. For a one-off diagnosis, since WordPress 5.1 WP_DEBUG_LOG accepts a path: put the log outside the web root, and turn display off.

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'WP_DEBUG_LOG', '/home/account/logs/wp-debug.log' ); // outside the web root

Remove these lines and the log file once the problem is solved.

Three columns of constants: to add (DISALLOW_FILE_EDIT, WP_DEBUG set to false, unique keys), to check (FORCE_SSL_ADMIN, automatic updates, environment), use with care (DISALLOW_FILE_MODS, salt rotation, debug log)
Security constants grouped by risk level.
ConstantRecommended production valueVerified effectPitfall
Keys and saltsUnique generated valuesSign cookies and noncesChanging them logs everyone out and can break encrypted data
DISALLOW_FILE_EDITtrueRemoves the file editorNone for most sites
DISALLOW_FILE_MODSOnly with external deploymentBlocks installs and updatesAlso turns off automatic updates
FORCE_SSL_ADMINtrueAdmin area over HTTPSAlready true by default if the site address uses https
WP_DEBUGfalseTurns off debug modeDefault log is public in wp-content
WP_AUTO_UPDATE_CORE'minor' (default) or trueControls automatic core updatesfalse also turns off security fixes
WP_ENVIRONMENT_TYPE'production'Declares the environment typeUnknown value: production by default
Summary of security constants

Where to put wp-config.php

One level above the root

The wp-load.php file looks for wp-config.php in the WordPress folder, then, if it does not find it there, one level up, provided that parent folder does not itself contain a wp-settings.php (so as not to confuse two nested installations). Placing the file outside the web root guarantees it can never be served by a simple request.

Directory tree with wp-config.php placed above the public_html folder, and the three lookup steps of wp-load.php
WordPress finds a wp-config.php placed one level above its root on its own.

The WordPress hardening guide acknowledges that the benefit is debated: as long as PHP is working, the file is never displayed, because it is executed. Moving it mainly protects against the case where the server stops executing PHP and serves files as plain text. On shared hosting where WordPress is installed directly in public_html, it is simple and safe; in a subfolder, check the structure first.

Permissions and server-level blocking

  • Permissions: the hardening guide recommends that only you and the web server can read the file, which usually means 400 or 440. Depending on the host, 600 or 640 may be needed.
  • On Apache or LiteSpeed, a <Files "wp-config.php"> block containing Require all denied in .htaccess blocks direct requests.
  • Never leave copies lying around: wp-config.php.bak, wp-config.old or wp-config.php~ are not executed by PHP and would be served as plain text, passwords included.

With WP Masquerade

WP Masquerade never modifies wp-config.php or core files. The free version's bot traps count requests for sensitive files such as .bak backups, which shows what bots are looking for on your site. In the Pro version, two-factor authentication encrypts user secrets with the site keys: its guide points out that after changing the keys, you need to log in with a backup code and then re-enable two-factor authentication. The integrity check compares core files against the official checksums, deliberately excluding wp-config.php, which is unique to each site.

Video in French (WPMarmite): three misconceptions about the wp-config.php file and its security.
Video in French: moving the wp-config.php file outside the web root.

Read also: Understanding WordPress errors and debugging your site.

Read also: How to install WordPress multisite and create a network of sites.

Key takeaways

  • Keys and salts sign cookies and nonces; generate them with the official service and change them only after a leak.
  • DISALLOW_FILE_EDIT is a safe measure; DISALLOW_FILE_MODS also turns off automatic updates.
  • FORCE_SSL_ADMIN is already on by default if the site address uses https.
  • In production: WP_DEBUG set to false, and never a log in a public folder.
  • WordPress accepts wp-config.php one level up; delete any backup copy of the file.

Sources

Other sources consulted: official vendor pages and security research publications.

WordPress security, without the noise

One e-mail when something matters: new attacks seen in the wild, plugin updates and practical guides. No spam, unsubscribe in one click.

Start free, go Pro when you’re ready

The free version already hides WordPress and moves the login page. Pro adds aliases, two-factor authentication and monitoring.