{
    "title": "wp-config.php: the security settings that really matter",
    "seo_title": "wp-config.php: WordPress security settings",
    "h1": "wp-config.php: the security settings that really matter",
    "description": "Keys and salts, DISALLOW_FILE_EDIT, DISALLOW_FILE_MODS, FORCE_SSL_ADMIN, WP_DEBUG in production, file location: what protects and what backfires.",
    "lead": "A few lines of wp-config.php change the security of a WordPress site, while others quietly weaken it. What each constant does according to the WordPress code, and the mistakes to avoid.",
    "language": "en",
    "locale": "en-US",
    "type": "article",
    "url": "https://www.wp-masquerade.com/wp-config-security-settings/",
    "canonical": "https://www.wp-masquerade.com/wp-config-security-settings/",
    "markdown": "https://www.wp-masquerade.com/wp-config-security-settings/index.md",
    "json": "https://www.wp-masquerade.com/wp-config-security-settings/index.json",
    "published": "2026-08-24T07:00:00+00:00",
    "modified": "2026-10-29T12:05:38+00:00",
    "site": {
        "name": "WP Masquerade",
        "url": "https://www.wp-masquerade.com/"
    },
    "translations": [
        {
            "language": "en",
            "hreflang": "en-US",
            "title": "wp-config.php: the security settings that really matter",
            "url": "https://www.wp-masquerade.com/wp-config-security-settings/",
            "markdown": "https://www.wp-masquerade.com/wp-config-security-settings/index.md",
            "json": "https://www.wp-masquerade.com/wp-config-security-settings/index.json"
        },
        {
            "language": "fr",
            "hreflang": "fr-FR",
            "title": "wp-config.php : les réglages de sécurité qui comptent vraiment",
            "url": "https://www.wp-masquerade.com/fr/wp-config-reglages-securite/",
            "markdown": "https://www.wp-masquerade.com/fr/wp-config-reglages-securite/index.md",
            "json": "https://www.wp-masquerade.com/fr/wp-config-reglages-securite/index.json"
        },
        {
            "language": "es",
            "hreflang": "es-ES",
            "title": "wp-config.php: los ajustes de seguridad que de verdad importan",
            "url": "https://www.wp-masquerade.com/es/wp-config-ajustes-seguridad/",
            "markdown": "https://www.wp-masquerade.com/es/wp-config-ajustes-seguridad/index.md",
            "json": "https://www.wp-masquerade.com/es/wp-config-ajustes-seguridad/index.json"
        },
        {
            "language": "de",
            "hreflang": "de-DE",
            "title": "wp-config.php: die Sicherheitseinstellungen, die wirklich zählen",
            "url": "https://www.wp-masquerade.com/de/wp-config-sicherheitseinstellungen/",
            "markdown": "https://www.wp-masquerade.com/de/wp-config-sicherheitseinstellungen/index.md",
            "json": "https://www.wp-masquerade.com/de/wp-config-sicherheitseinstellungen/index.json"
        },
        {
            "language": "it",
            "hreflang": "it-IT",
            "title": "wp-config.php: le impostazioni di sicurezza che contano davvero",
            "url": "https://www.wp-masquerade.com/it/wp-config-impostazioni-sicurezza/",
            "markdown": "https://www.wp-masquerade.com/it/wp-config-impostazioni-sicurezza/index.md",
            "json": "https://www.wp-masquerade.com/it/wp-config-impostazioni-sicurezza/index.json"
        },
        {
            "language": "pt",
            "hreflang": "pt-BR",
            "title": "wp-config.php: as configurações de segurança que realmente importam",
            "url": "https://www.wp-masquerade.com/pt/wp-config-configuracoes-seguranca/",
            "markdown": "https://www.wp-masquerade.com/pt/wp-config-configuracoes-seguranca/index.md",
            "json": "https://www.wp-masquerade.com/pt/wp-config-configuracoes-seguranca/index.json"
        },
        {
            "language": "nl",
            "hreflang": "nl-NL",
            "title": "wp-config.php: de beveiligingsinstellingen die er echt toe doen",
            "url": "https://www.wp-masquerade.com/nl/wp-config-beveiligingsinstellingen/",
            "markdown": "https://www.wp-masquerade.com/nl/wp-config-beveiligingsinstellingen/index.md",
            "json": "https://www.wp-masquerade.com/nl/wp-config-beveiligingsinstellingen/index.json"
        }
    ],
    "headings": [
        {
            "level": 1,
            "text": "wp-config.php: the security settings that really matter"
        },
        {
            "level": 2,
            "text": "Keys and salts: what they are really for"
        },
        {
            "level": 3,
            "text": "Should you rotate them regularly?"
        },
        {
            "level": 2,
            "text": "Turning off the file editor: DISALLOW_FILE_EDIT"
        },
        {
            "level": 2,
            "text": "DISALLOW_FILE_MODS: stronger, and riskier"
        },
        {
            "level": 2,
            "text": "FORCE_SSL_ADMIN: often already on"
        },
        {
            "level": 2,
            "text": "WP_DEBUG in production"
        },
        {
            "level": 2,
            "text": "Where to put wp-config.php"
        },
        {
            "level": 3,
            "text": "One level above the root"
        },
        {
            "level": 3,
            "text": "Permissions and server-level blocking"
        },
        {
            "level": 2,
            "text": "With WP Masquerade"
        },
        {
            "level": 3,
            "text": "Key takeaways"
        },
        {
            "level": 2,
            "text": "Sources"
        },
        {
            "level": 2,
            "text": "WordPress security, without the noise",
            "id": "wpm-nl-box-title"
        }
    ],
    "body": "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.\n\n## Keys and salts: what they are really for\n\nThe 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.\n\nTwo common misconceptions need correcting:\n\n- they are **not used to hash user passwords**. Since WordPress 6.8, passwords are hashed with [bcrypt](https://www.wp-masquerade.com/glossary/bcrypt/), independently of these constants;\n- changing them **logs everyone out**: the comment in the template file says so, all sessions become invalid.\n\nGenerate them with the official service `https://api.wordpress.org/secret-key/1.1/salt/`, which returns eight lines ready to paste.\n\n### Should you rotate them regularly?\n\nNo, 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](https://www.wp-masquerade.com/glossary/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.\n\n## Turning off the file editor: DISALLOW_FILE_EDIT\n\nBy 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.\n\n```\ndefine( 'DISALLOW_FILE_EDIT', true );\n```\n\nAccording 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.\n\n## DISALLOW_FILE_MODS: stronger, and riskier\n\n`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.\n\nReserve 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.\n\n## FORCE_SSL_ADMIN: often already on\n\n`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.\n\n## WP_DEBUG in production\n\nDebugging is essential in development and dangerous in production, for two reasons.\n\n- **Displaying errors** (`WP_DEBUG_DISPLAY`, true by default when `WP_DEBUG` is on) reveals file paths, queries and plugin names to any visitor.\n- **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.\n\nIn 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.\n\n```\ndefine( 'WP_DEBUG', true );\ndefine( 'WP_DEBUG_DISPLAY', false );\ndefine( 'WP_DEBUG_LOG', '/home/account/logs/wp-debug.log' ); // outside the web root\n```\n\nRemove these lines and the log file once the problem is solved.\n\n![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)](https://www.wp-masquerade.com/media/2026/10/constantes-en.webp)\n\n*Security constants grouped by risk level.*\n\n| Constant | Recommended production value | Verified effect | Pitfall |\n| --- | --- | --- | --- |\n| Keys and salts | Unique generated values | Sign cookies and nonces | Changing them logs everyone out and can break encrypted data |\n| `DISALLOW_FILE_EDIT` | `true` | Removes the file editor | None for most sites |\n| `DISALLOW_FILE_MODS` | Only with external deployment | Blocks installs and updates | Also turns off automatic updates |\n| `FORCE_SSL_ADMIN` | `true` | Admin area over HTTPS | Already true by default if the site address uses https |\n| `WP_DEBUG` | `false` | Turns off debug mode | Default log is public in wp-content |\n| `WP_AUTO_UPDATE_CORE` | `'minor'` (default) or `true` | Controls automatic core updates | `false` also turns off security fixes |\n| `WP_ENVIRONMENT_TYPE` | `'production'` | Declares the environment type | Unknown value: `production` by default |\n\n*Summary of security constants*\n\n## Where to put wp-config.php\n\n### One level above the root\n\nThe `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.\n\n![Directory tree with wp-config.php placed above the public_html folder, and the three lookup steps of wp-load.php](https://www.wp-masquerade.com/media/2026/10/emplacement-en.webp)\n\n*WordPress finds a wp-config.php placed one level above its root on its own.*\n\nThe 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](https://www.wp-masquerade.com/glossary/shared-hosting/) where WordPress is installed directly in `public_html`, it is simple and safe; in a subfolder, check the structure first.\n\n### Permissions and server-level blocking\n\n- 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.\n- On Apache or LiteSpeed, a `<Files \"wp-config.php\">` block containing `Require all denied` in `.htaccess` blocks direct requests.\n- 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.\n\n## With WP Masquerade\n\nWP Masquerade never modifies `wp-config.php` or core files. The free version's [bot traps](https://www.wp-masquerade.com/features/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](https://www.wp-masquerade.com/features/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](https://www.wp-masquerade.com/features/wordpress-integrity-check/) compares core files against the official checksums, deliberately excluding `wp-config.php`, which is unique to each site.\n\n*Video in French (WPMarmite): three misconceptions about the wp-config.php file and its security.*\n\n*Video in French: moving the wp-config.php file outside the web root.*\n\nRead also: [Understanding WordPress errors and debugging your site](https://www.wp-masquerade.com/wordpress-errors-debugging-guide/).\n\nRead also: [How to install WordPress multisite and create a network of sites](https://www.wp-masquerade.com/install-wordpress-multisite-network/).\n\n### Key takeaways\n\n- Keys and salts sign cookies and nonces; generate them with the official service and change them only after a leak.\n- `DISALLOW_FILE_EDIT` is a safe measure; `DISALLOW_FILE_MODS` also turns off automatic updates.\n- `FORCE_SSL_ADMIN` is already on by default if the site address uses https.\n- In production: `WP_DEBUG` set to false, and never a log in a public folder.\n- WordPress accepts wp-config.php one level up; delete any backup copy of the file.\n\n## Sources\n\n- [WordPress Developer Resources: Editing wp-config.php](https://developer.wordpress.org/advanced-administration/wordpress/wp-config/)\n- [WordPress Developer Resources: Hardening WordPress](https://developer.wordpress.org/advanced-administration/security/hardening/)\n- [Make WordPress Core: WordPress 6.8 will use bcrypt for password hashing](https://make.wordpress.org/core/2025/02/17/wordpress-6-8-will-use-bcrypt-for-password-hashing/)\n- [Official key generator: api.wordpress.org/secret-key/1.1/salt/](https://api.wordpress.org/secret-key/1.1/salt/)\n\nOther sources consulted: official vendor pages and security research publications.\n\n## WordPress security, without the noise\n\nOne e-mail when something matters: new attacks seen in the wild, plugin updates and practical guides. No spam, unsubscribe in one click.",
    "categories": [
        "Hardening"
    ],
    "format": "application/json"
}