Category: WordPress Security
The wp-config.php file is one of the most sensitive files in a WordPress website. It contains database credentials, authentication keys, salts, table prefix settings, debug constants, memory settings, and other configuration values that help WordPress connect to the database and run correctly.
If an attacker can read, download, modify, or expose your wp-config.php file, they may gain access to database credentials, break the site, inject malicious configuration, expose debug data, or make cleanup much harder after a compromise.
This guide explains how to protect wp-config.php from attacks using practical WordPress hardening steps, file permissions, Apache and Nginx rules, backup safety, debug settings, salts, and common mistakes to avoid.
TL;DR: Best wp-config.php Protection Steps
Protect wp-config.php by setting strict file permissions, blocking direct web access, keeping it out of public backups, disabling dashboard file editing, turning off public debug display, regenerating salts after compromise, avoiding hardcoded insecure dynamic URLs, protecting database credentials, and using secure hosting. On Apache, deny direct access with a <Files "wp-config.php"> rule. On Nginx, deny access in the server block. On some servers, you can also move wp-config.php one directory above the WordPress installation, but only if your hosting setup supports it safely.
Why wp-config.php Is So Important
The wp-config.php file is created during WordPress installation and lives in the WordPress root directory by default. It tells WordPress how to connect to the database and how to handle important configuration settings.
wp-config.php usually contains:
- Database name.
- Database username.
- Database password.
- Database host.
- Authentication keys and salts.
- Database table prefix.
- Debug settings.
- Memory limits.
- SSL/admin constants.
- File editing restrictions.
- Advanced WordPress configuration constants.
Because it contains sensitive configuration, you should treat wp-config.php like a password file. It should never be publicly downloadable, world-writable, exposed in backups, shared in support tickets without redaction, or left with unsafe debug settings.
Official reference: Editing wp-config.php.
1. Back Up Before Editing wp-config.php
Before changing wp-config.php, create a safe backup. A small typo can break the entire website and show a database connection error, white screen, or critical error.
Safe backup process:
- Download a copy of
wp-config.phpthrough SFTP or File Manager. - Save it somewhere private, not inside a public web folder.
- Do not upload it to public tools, public Git repositories, or unsecured support chats.
- After editing, test the website and dashboard immediately.
- Delete temporary copies when they are no longer needed.
Never create files like wp-config-backup.php, wp-config-old.php, wp-config.txt, or wp-config.php.bak inside your public website directory. Attackers and bots commonly scan for backup files.
2. Set Strict File Permissions
File permissions control who can read, write, or execute a file. Your wp-config.php file should be readable only by the user/server process that needs it. It should not be writable by everyone.
Common permission options:
| Permission | Meaning | When It May Be Used |
|---|---|---|
400 |
Owner can read only | Very strict setups where the server can still read it |
440 |
Owner/group can read | Common secure option when web server reads through group ownership |
600 |
Owner can read/write | Common secure option on some hosting setups |
640 |
Owner can read/write, group can read | Common when group read access is needed |
644 |
Owner can write, others can read | Works on many hosts but is less strict |
777 |
Everyone can read, write, and execute | Do not use for wp-config.php |
SSH examples:
# Very strict; may not work on every host
chmod 400 wp-config.php
# Common secure option when group access is required
chmod 440 wp-config.php
# Common secure option on some hosting setups
chmod 600 wp-config.php
# Common secure option where web server needs group read access
chmod 640 wp-config.php
Important warning:
Do not blindly copy a permission value without understanding your hosting setup. If permissions are too strict, WordPress may not be able to read the file. If permissions are too loose, the file may be easier to expose or modify. Start strict, test the site, and ask your host if the site breaks.
Official reference: Changing File Permissions.
3. Block Direct Web Access on Apache
Even though PHP files are normally processed by the server, you should still block direct browser access to wp-config.php. This adds a server-level protection layer in case the server is misconfigured.
Add this rule near the top of your root .htaccess file, outside the WordPress-generated section:
<Files "wp-config.php">
Require all denied
</Files>
Where to place it:
# Place custom security rules above this line when possible.
# BEGIN WordPress
# WordPress-generated rules are here.
# END WordPress
Do not place custom rules between # BEGIN WordPress and # END WordPress because WordPress may overwrite that section when permalink rules are regenerated.
FyrePress tool: For Apache/LiteSpeed security rule examples, use the FyrePress .htaccess Security Builder.
4. Block Direct Web Access on Nginx
Nginx does not use .htaccess. If your WordPress site runs on Nginx, add the protection inside your Nginx server block.
Nginx example:
location = /wp-config.php {
deny all;
}
Alternative stricter pattern:
location ~* /wp-config\.php$ {
deny all;
}
After editing Nginx configuration, test and reload Nginx:
nginx -t
systemctl reload nginx
If you are on managed hosting, ask support to apply the rule. Do not edit Nginx configuration on a production server unless you know how to test and reload safely.
5. Consider Moving wp-config.php One Level Above WordPress
WordPress can load wp-config.php from one directory level above the WordPress installation. This can keep the file outside the public WordPress root in some hosting setups.
Example structure:
/home/account/wp-config.php
/home/account/public_html/wp-admin/
/home/account/public_html/wp-content/
/home/account/public_html/wp-includes/
When this can help:
- Your hosting setup allows WordPress to read the parent directory.
- The parent directory is outside the public web root.
- You understand file ownership and permissions.
- You can test the change safely.
When to avoid it:
- Your host does not support this setup.
- You are not sure which directory is public.
- You use a deployment tool that expects
wp-config.phpin the root. - You may accidentally move it to another public directory.
- You cannot test the change on staging first.
Moving wp-config.php is not a magic security fix. It can help in some setups, but bad permissions, exposed backups, weak hosting, and compromised admin access can still create risk.
6. Disable Dashboard File Editing
If an attacker gains administrator access, the dashboard file editor can become a direct path to modifying theme or plugin PHP files. Disabling file editing reduces the damage an attacker can do from inside wp-admin.
Add this line above the final stop-editing comment in wp-config.php:
define( 'DISALLOW_FILE_EDIT', true );
Correct placement:
define( 'DISALLOW_FILE_EDIT', true );
/* That's all, stop editing! Happy publishing. */
This does not stop all attacks. It does not prevent malicious uploads, compromised SFTP access, or server-level modification. But it removes one common code-editing path from the WordPress dashboard.
FyrePress tool: Use the FyrePress wp-config.php Builder to generate reviewable wp-config.php constants before editing the live file.
7. Keep Debug Output Private
Debug settings are useful for development, but dangerous when exposed on a live site. Public errors can reveal server paths, plugin names, theme files, database details, or sensitive logic.
Safe production settings:
define( 'WP_DEBUG', false );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );
Temporary private logging for troubleshooting:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );
WordPress normally logs to wp-content/debug.log when WP_DEBUG_LOG is enabled. That file may be publicly accessible on some setups if not protected properly.
Safer custom log path:
define( 'WP_DEBUG_LOG', '/home/account/private-logs/wp-errors.log' );
Use a path outside the public web root if your host supports it.
Apache rule to block debug.log:
<Files "debug.log">
Require all denied
</Files>
Official reference: Debugging in WordPress.
FyrePress tool: If your site generated PHP or server logs, review excerpts with the FyrePress Server Log Analyzer.
8. Regenerate Security Keys and Salts After a Compromise
WordPress security keys and salts help protect authentication cookies and logged-in sessions. If your wp-config.php file may have been exposed, regenerate the keys and salts.
Keys and salts look like this:
define( 'AUTH_KEY', '...' );
define( 'SECURE_AUTH_KEY', '...' );
define( 'LOGGED_IN_KEY', '...' );
define( 'NONCE_KEY', '...' );
define( 'AUTH_SALT', '...' );
define( 'SECURE_AUTH_SALT', '...' );
define( 'LOGGED_IN_SALT', '...' );
define( 'NONCE_SALT', '...' );
Use the official WordPress.org secret-key generator: WordPress.org Secret Key Service.
When to regenerate salts:
- After a suspected hack.
- After admin credentials are leaked.
- After
wp-config.phpwas exposed. - After restoring a compromised site.
- After removing unknown admin users.
- After changing database credentials during cleanup.
Changing salts logs out all users. That is expected and useful after a security incident.
9. Protect Database Credentials
The database credentials inside wp-config.php should not be reused across multiple sites. If one website is compromised, shared credentials can increase the damage.
Database credential checklist:
- Use a unique database name for each site.
- Use a unique database user for each site.
- Use a strong database password.
- Do not reuse database credentials across multiple WordPress installs.
- Restrict remote database access unless required.
- Change database credentials after a compromise.
- Update
wp-config.phpimmediately after rotating credentials.
Example database section:
define( 'DB_NAME', 'example_database' );
define( 'DB_USER', 'example_user' );
define( 'DB_PASSWORD', 'strong_unique_password_here' );
define( 'DB_HOST', 'localhost' );
Never share screenshots or copies of this section publicly unless credentials are fully redacted.
10. Do Not Store Public Backup Copies
Many wp-config.php leaks happen because someone creates a backup copy in the public web directory. Attackers scan for common backup names.
Dangerous file names:
wp-config.php.bakwp-config.php.oldwp-config.php.savewp-config.txtwp-config-backup.phpwp-config copy.phpbackup.zipsite-backup.tar.gzdatabase.sql
Safe backup rules:
- Store backups outside public web folders.
- Encrypt sensitive backups when possible.
- Delete temporary migration archives after use.
- Never upload full site backups to a public URL.
- Check the website root for old archives after migrations.
A secured wp-config.php is not enough if wp-config.php.bak is publicly downloadable.
11. Be Careful With Dynamic Site URLs
Some developers define site URLs dynamically in wp-config.php using request headers. This can be risky if it depends on untrusted values.
Risky example:
define( 'WP_HOME', 'https://' . $_SERVER['HTTP_HOST'] );
define( 'WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST'] );
The problem is that HTTP_HOST comes from the request and may be manipulated in some server configurations. In many sites, fixed values are safer.
Safer fixed example:
define( 'WP_HOME', 'https://example.com' );
define( 'WP_SITEURL', 'https://example.com' );
Dynamic configuration can be useful in advanced deployment workflows, but it should be handled carefully by developers who understand host header behavior, reverse proxies, and environment-specific configuration.
12. Remove Secrets From Git and Public Repositories
Developers should never commit real wp-config.php files with production credentials into Git repositories, especially public ones.
Safer Git workflow:
- Add
wp-config.phpto.gitignore. - Use
wp-config-sample.phpfor placeholder values. - Store secrets in environment variables where appropriate.
- Use deployment secrets in CI/CD tools.
- Rotate credentials immediately if secrets were committed.
- Clean Git history if secrets were pushed to a remote repository.
.gitignore example:
wp-config.php
*.sql
*.zip
*.tar.gz
.env
debug.log
If production credentials were pushed to GitHub, GitLab, Bitbucket, or another remote repository, deleting the file in a later commit is not enough. Rotate the credentials.
13. Protect wp-config.php During Support Work
Many leaks happen during support, migration, or troubleshooting. A developer or support agent asks for “the config file,” and the site owner sends the full file with database credentials visible.
Before sharing wp-config.php:
- Remove database name, username, password, and host.
- Remove salts and authentication keys.
- Remove private API keys or custom constants.
- Remove absolute server paths if not needed.
- Share only the specific lines needed for troubleshooting.
- Use a private secure support channel, not public forums.
Redacted example:
define( 'DB_NAME', 'REDACTED' );
define( 'DB_USER', 'REDACTED' );
define( 'DB_PASSWORD', 'REDACTED' );
define( 'DB_HOST', 'REDACTED' );
If you accidentally shared the full file with untrusted people, rotate database credentials and salts.
14. Use a Web Application Firewall
A firewall does not replace file permissions or server rules, but it can block many scans and suspicious requests before they reach WordPress.
A WAF can help block:
- Requests for backup config files.
- Known exploit patterns.
- Suspicious query strings.
- Bot scans for sensitive files.
- Repeated login attempts.
- Malicious file upload attempts.
Use a firewall at the CDN, host, server, or WordPress plugin level. For high-value sites, server/CDN-level filtering is usually better because malicious requests can be blocked before WordPress loads.
15. Test Whether wp-config.php Is Protected
After adding protection, test direct access from a browser or terminal.
Browser test:
https://example.com/wp-config.php
You should not see file contents. Ideally, the server should return a forbidden, not found, or empty response depending on configuration.
cURL test:
curl -I https://example.com/wp-config.php
Good signs:
403 Forbidden404 Not Found- No sensitive output
- No PHP source code displayed
- No database credentials visible
Also test common backup file names if you recently edited or migrated the site.
wp-config.php Protection Checklist
Use this checklist for every WordPress site.
- Take a private backup before editing
wp-config.php. - Set strict file permissions such as
400,440,600, or640depending on hosting setup. - Never use
777permissions. - Block direct web access with Apache or Nginx rules.
- Consider moving
wp-config.phpone level above WordPress only if your host supports it safely. - Add
DISALLOW_FILE_EDIT. - Keep public debug display disabled.
- Move debug logs outside the web root where possible.
- Regenerate salts after compromise or exposure.
- Use unique database credentials per site.
- Do not store public backup copies.
- Do not commit real credentials to Git.
- Redact secrets before support sharing.
- Use a firewall to reduce sensitive file scans.
- Test direct access after hardening.
Best Method by Hosting Type
For shared hosting users
Use strict permissions your host supports, add the Apache .htaccess deny rule if applicable, disable file editing, keep backups outside public folders, and ask support before moving wp-config.php.
For cPanel users
Use File Manager or SFTP to edit carefully, avoid public backup copies, check permissions, and place custom rules outside the WordPress-generated .htaccess section.
For Nginx VPS users
Add a server block rule to deny access to wp-config.php, test Nginx config before reload, set strict ownership and permissions, and keep secrets out of public repositories.
For agencies
Create a standard hardening baseline: permissions, server deny rules, DISALLOW_FILE_EDIT, private backups, redacted support procedures, credential rotation, and post-migration cleanup.
For developers
Use environment-specific config, avoid committing secrets, automate permission checks, rotate credentials after exposure, and document where production secrets are stored.
Common Mistakes to Avoid
- Leaving
wp-config.php.bakin the public root. - Using
777permissions to “fix” editing issues. - Sharing full
wp-config.phpin public support forums. - Leaving
WP_DEBUG_DISPLAYenabled on production. - Committing database credentials to Git.
- Moving
wp-config.phpincorrectly and breaking WordPress. - Assuming a security plugin alone protects the file.
- Forgetting to rotate salts after a compromise.
- Using one database user for multiple WordPress sites.
- Putting custom
.htaccessrules inside the WordPress-generated section.
Final Recommendation
The best way to protect wp-config.php is to combine multiple layers: strict file permissions, server-level access blocking, private backups, safe debug settings, disabled dashboard file editing, unique database credentials, and careful credential handling.
Do not rely on one trick. Moving wp-config.php may help in some setups, but it does not replace permissions, server rules, backup hygiene, secure hosting, and credential rotation.
For most WordPress sites, start with the essentials: deny direct web access, tighten permissions, remove public backup copies, disable file editing, turn off public debug output, and regenerate salts after any suspected exposure.
Frequently Asked Questions
What is wp-config.php in WordPress?
wp-config.php is the main WordPress configuration file. It contains database connection details, authentication keys, salts, table prefix settings, debug constants, and other important configuration values.
Can hackers access wp-config.php?
A properly configured server should not expose wp-config.php. However, misconfigured servers, public backup copies, weak file permissions, malware, or exposed repositories can leak the file.
What permissions should wp-config.php have?
Secure permissions depend on hosting setup, but common options include 400, 440, 600, or 640. Avoid 777. If the site breaks, ask your host which strict permission works with their server ownership model.
Should I move wp-config.php outside the WordPress root?
You can move wp-config.php one directory level above the WordPress installation if your hosting setup supports it. This can help in some setups, but it is not a complete security solution and should be tested carefully.
How do I block direct access to wp-config.php on Apache?
Add <Files "wp-config.php"> Require all denied </Files> near the top of your root .htaccess file, outside the WordPress-generated rules.
How do I block direct access to wp-config.php on Nginx?
Add a rule such as location = /wp-config.php { deny all; } inside the Nginx server block, then test and reload Nginx.
Should I disable file editing in wp-config.php?
Yes, for most production sites. Add define( 'DISALLOW_FILE_EDIT', true ); to prevent administrators from editing plugin and theme files through the WordPress dashboard.
Is it safe to keep WP_DEBUG enabled?
WP_DEBUG should normally be disabled on live sites. If you need temporary logging, keep WP_DEBUG_DISPLAY false and store logs privately so errors are not shown to visitors.
Should I regenerate WordPress salts?
Regenerate salts after a suspected hack, credential leak, exposed wp-config.php, unknown admin account, or cleanup. This logs out all users and invalidates existing sessions.
Can I share wp-config.php with support?
Only share the specific lines needed for troubleshooting, and redact database credentials, salts, API keys, paths, and private constants. Never post the full file in a public forum.