Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

One of the most common security best practices these days seems to be moving wp-config.php one directory higher than the vhost's document root. I've never really found a good explanation for that, but I'm assuming it's to minimize the risk of a malicious or infected script within the webroot from reading the database password.

But, you still have to let WordPress access it, so you need to expand open_basedir to include the directory above the document root. Doesn't that just defeat the entire purpose, and also potentially expose server logs, backups, etc to attackers?

Or is the technique only trying to prevent a situation where wp-config.php would be shown as plain-text to anyone requesting http://example.com/wp-config.php, instead of being parsed by the PHP engine? That seems like a very rare occurance, and it wouldn't outweigh the downsides of exposing logs/backups/etc to HTTP requests.

Maybe it's possible to move it outside the document root in some hosting setups without exposing other files, but not in other setups?


Conclusion: After a lot of back-and-forth on this issue, two answers have emerged that I think should be considered the authoritative ones. Aaron Adams makes a good case in favor of moving wp-config, and chrisguitarguy makes a good case against it. Those are the two answers you should read if you're new to the thread and don't want to read the entire thing. The other answers are either redundant or inaccurate.

share|improve this question
    
It's really not necessary to plug your choice of answers and reject all other answers, inside your question. As you can see below, that's what the stackexchange voting system is for, to vote up the answers that make sense to people, whereas the question askers should be using the "accepted answer" mechanism and your own up/down votes. –  Kzqai Jan 20 at 16:53
1  
I don't do that for 99% of the questions I've asked, but I thought it was appropriate in this specific case. There are 8 answers to the question, some of which are fairly lengthly/complex, and some of which have a lot of upvotes despite despite containing inaccurate info or not adding anything to the conversation. I think offering a semi-authoritative conclusion is helpful to people reading the thread for the first time. As always, readers are free to make up their own mind; I'm just offering my opinion as the OP. –  Ian Dunn Jan 21 at 0:15
add comment

8 Answers

up vote 31 down vote accepted

Short answer: yes

The answer to this question is an unequivocal yes, and to say otherwise is completely irresponsible.


Long answer: a real-world example

Allow me to provide a very real example, from my very real server, where moving wp-config.php outside the web root specifically prevented its contents from being captured.

The bug:

Take a look at this description of a bug in Plesk (fixed in 11.0.9 MU#27):

Plesk resets subdomain forwarding after syncing subscription with hosting plan (117199)

Sounds harmless, right?

Well, here's what I did to trigger this bug:

  1. Set up a subdomain to redirect to another URL (e.g. site.staging.server.com to site-staging.ssl.server.com).
  2. Changed the subscription's service plan (e.g. its PHP configuration).

When I did this, Plesk reset the subdomain to defaults: serving the contents of ~/httpdocs/, with no interpreters (e.g. PHP) active.

And I didn't notice. For weeks.

The result:

  • With wp-config.php in the web root, a request to /wp-config.php would have downloaded the WordPress configuration file.
  • With wp-config.php outside the web root, a request to /wp-config.php downloaded a completely harmless file. The real wp-config.php file could not be downloaded.

Thus, it's obvious that moving wp-config.php outside the web root has bona fide security benefits in the real world.


How to move wp-config.php to any location on your server

WordPress will automatically look one directory above your WordPress installation for your wp-config.php file, so if that's where you've moved it, you're done!

But what if you've moved it somewhere else? Easy. Create a new wp-config.php in the WordPress directory with the following code:

<?php

/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
    define('ABSPATH', dirname(__FILE__) . '/');

/** Location of your WordPress configuration. */
require_once(ABSPATH . '../phpdocs/wp-config.php');

(Be sure to change the above path to the actual path of your relocated wp-config.php file.)

If you run into a problem with open_basedir, just add the new path to the open_basedir directive in your PHP configuration:

open_basedir = "/var/www/vhosts/example.com/httpdocs/;/var/www/vhosts/example.com/phpdocs/;/tmp/"

That's it!


Picking apart arguments to the contrary

Every argument against moving wp-config.php outside the web root hinges on false assumptions.

Argument 1: If PHP is disabled, they're already in

The only way someone is going to see that contents of [wp-config.php] is if they circumvent your servers PHP interpreter… If that happens, you're already in trouble: they have direct access to your server.

FALSE: The scenario I describe above is the result of a misconfiguration, not an intrusion.

Argument 2: Accidentally disabling PHP is rare, and therefore insignificant

If an attacker has enough access to change the PHP handler, you're already screwed. Accidental changes are very rare in my experience, and in that case it'd be easy to change the password.

FALSE: The scenario I describe above is the result of a bug in a common piece of server software, affecting a common server configuration. This is hardly "rare" (and besides, security means worrying about the rare scenario).

WTF: Changing the password after an intrusion hardly helps if sensitive information was picked up during the intrusion. Really, do we still think WordPress is only used for casual blogging, and that attackers are only interested in defacement? Let's worry about protecting our server, not just restoring it after somebody gets in.

Argument 3: Denying access to wp-config.php is good enough

You can restrict access to the file via your virtual host config or .htaccess – effectively limiting outside access to the file in the same way that moving outside the document root would.

FALSE: Imagine your server defaults for a virtual host are: no PHP, no .htaccess, allow from all (hardly unusual in a production environment). If your configuration is somehow reset during a routine operation – like, say, a panel update – everything will revert to its default state, and you're exposed.

If your security model fails when settings are accidentally reset to defaults, you need more security.

WTF: Why would anybody specifically recommend fewer layers of security? Expensive cars don't just have locks; they also have alarms, immobilizers, and GPS trackers. If something's worth protecting, do it right.

Argument 4: Unauthorized access to wp-config.php is no big deal

The database information is really the only sensitive stuff in [wp-config.php].

FALSE: The authentication keys and salts can be used in any number of potential hijacking attacks.

WTF: Even if database credentials were the only thing in wp-config.php, you should be terrified of an attacker getting their hands on them.

Argument 5: Moving wp-config.php outside the web root actually makes a server less secure

You still have to let WordPress access [wp-config.php], so you need to expand open_basedir to include the directory above the document root.

FALSE: Assuming wp-config.php is in httpdocs/, just move it to ../phpdocs/, and set open_basedir to include only httpdocs/ and phpdocs/. For instance:

open_basedir = "/var/www/vhosts/example.com/httpdocs/;/var/www/vhosts/example.com/phpdocs/;/tmp/"

(Remember to always include /tmp/, or your user tmp/ directory, if you have one.)


Conclusion: configuration files should always always always be located outside the web root

If you care about security, you will move wp-config.php outside your web root.

share|improve this answer
1  
If you have a bug in apache, linux or the brain of the admin you are a toast in any case. In your scenario you fail to explain why it is more probable for a misconfiguration to happen at the root of the web site then in any other place on the server. A misconfigured apache can probably access /../config.php as easy as /config.php –  Mark Kaplun Dec 4 '12 at 21:14
1  
You are not "toast in any case." It is very probable, and even demonstrable, that a bug would result in the web root being reset to its default, in which case you are not "toast" – your wp-config.php remains safe. And it is extremely improbable – so much so as to essentially be impossible – that a bug would result in the web root being arbitrarily reset to the exact directory in which you placed your wp-config.php. –  Aaron Adams Dec 4 '12 at 21:23
1  
@IanDunn Actually, it's easy to move wp-config.php to an arbitrary location. I've added directions to my answer; it just involves creating a dummy wp-config.php in the WordPress directory referencing the location of the real one. –  Aaron Adams Dec 6 '12 at 4:07
1  
This response is spot-on. My web hosting company had a drive array failure. When all was said & done they restored the system PARTIALLY. Turns out they used a series of cPanel/WHM scripts to rebuild httpd.conf files that did so incorrectly. Luckily I already had wp-config.php outside of the doc root, but if I hadn't the contents were there for the taking. Yes rare, but as noted the rare cases are what you need to worry about. Also, stating "simple minded folk would be lost" is a bad excuse for having LESS security. –  Charleston Software Associates Dec 6 '12 at 5:46
1  
That's a good point, Aaron. I'm still a little skeptical for the reasons I've mentioned in this and other comment thread, but you've convinced me that it has more merit than I originally thought. At the very least, if done properly, I don't think it will hurt anything. I still have a problem with the fact that most people promoting it don't seem to understand the reasons for it, and the way they teach it would often lead to the directory above httpdocs being exposed, but you've helped address those issues in your answer. –  Ian Dunn Dec 6 '12 at 16:56
show 7 more comments

I think Max's is a knowledgeable answer, and that's one side of the story. The WordPress Codex has more advise:

Also, make sure that only you (and the web server) can read this file (it generally means a 400 or 440 permission).

If you use a server with .htaccess, you can put this in that file (at the very top) to deny access to anyone surfing for it:

<files wp-config.php>
order allow,deny
deny from all
</files>

Note that setting 400 or 440 permission on wp-config.php may prevent plugins from writing to or modifying it. A genuine case for example would be, caching plugins (W3 Total Cache, WP Super Cache, etc.) In that case, I'd go with 600 (the default permission for files in /home/user directory).

share|improve this answer
5  
Max's is the answer. +1 to him. I am simply trying to extend it. –  its_me Jul 13 '12 at 16:15
1  
Aahan Krish, you've hit the bull's eye. Thanks for the addition. –  Max Yudin Jul 13 '12 at 16:26
    
So if you use htaccess to deny HTTP requests to wp-config.php, doesn't that achieve the same result as moving it outside the document root, but without exposing logs/backups/etc? –  Ian Dunn Jul 13 '12 at 17:59
4  
@IanDunn Depends on what the document root is— (1) If wordpress is hosted in a directory in public_html, moving wp-config.php outside the directory means that it's going to be in public_html directory. In this case, you'll have to use the htaccess rules to deny HTTP requests to wp-config.php. (2) If WordPress is installed directly under public_html directory, one level up => you'll be moving it into /home/user directory. In this case you are pretty safe as the file is outside the document root. You can still set the file's permissions to 600 (or even stricter 440 or 400). –  its_me Jul 13 '12 at 18:10
    
@IanDunn Like I said, this is my basic understanding, and I am no security expert. :) –  its_me Jul 13 '12 at 18:10
show 2 more comments

The biggest thing is the wp-config.php contains some sensitive information: your database username/password, etc.

So the idea: move it outside the document root, and you don't have to worry about anything. An attacker will never be able to access that file from an external source.

Here's the rub, however: wp-config.php never actually prints anything to the screen. It only defines various constants that are used throughout your WP install. Thus the only way someone is going to see that contents of that file is if they circumvent your servers PHP interpreter -- they get .php file to render as just plain text. If that happens, you're already in trouble: they have direct access to your server (and probably root permissions) and can do whatever they like.

I'm going to go ahead and say there's no benefit to moving wp-config outside the document root from a security perspective -- for the reasons above and these:

  1. You can restrict access to the file via your virtual host config or .htaccess -- effectively limiting outside access to the file in the same way that moving outside the document root would
  2. You can ensure the file permissions are strict on wp-config to prevent any user without sufficient privileges from reading the file even if they gain (limited) access to your server via SSH.
  3. Your sensitive information, database settings, are only used on a single site. So even if an attacker gained access to that information, the only site it would affect would be the WordPress install to which the wp-config.php file belongs. More importantly, that database user only has permissions to read and write to that WP install's database and and nothing else -- no access to grant other users permissions. Meaning, in otherwords, if an attacker gains access to your database, it's simply a matter of restoring from a backup (see point 4) and changing the database user
  4. You backup often. Often being a relative term: if you post 20 article every day, you better back up every day or every few days. If you post once a week, backing up once a week is likely sufficient.
  5. You have your site under version control (like this), which means even if an attacker gained access, you can easily detect code changes and roll them back. If an attacker has access to wp-config, they've probably messed with something else.
  6. The database information is really the only sensitive stuff in wp-config, and because you're careful about it (see point 3 and 4), it's not a huge deal. Salts and such can be changed any time. The only thing that happens is that it invalidates logged in users' cookies.

To me, moving wp-config out of the document root reeks of security by obscurity -- which is very much a straw man.

share|improve this answer
2  
Yeah, that's pretty much what I've been thinking. I'm glad to know I'm not the only one :) I'd like to leave the question open for another day or two just in case somebody has a compelling counter-argument, but so far this seems like the right answer to me. –  Ian Dunn Jul 18 '12 at 1:56
3  
Minor correction: There's no security benefit to moving the wp-config.php file out of the document root. There are other benefits, which are not security related, and which only apply to unusual setups. –  Otto Aug 12 '12 at 15:19
    
Good call. Edited. –  chrisguitarguy Aug 12 '12 at 16:36
2  
Just to get a possible myth debunked - is it not possible, something might go wrong server side - in which case php code is printed to the screen? –  Stephen Harris Aug 12 '12 at 18:49
1  
@IanDunn But the best answers advocate moving it out of that hierarchy altogether into a separate one, which does address your concern about logs etc. This answer doesn't answer your question title "is moving ... really beneficial", it just says other security measures are beneficial, and tries to reassure you into not worrying about security. Everyone thinks their house is secure until they get burgled. After that they do a better job. Some people never get burgled, even though their security is low, but it doesn't mean it's good advice to have lower security. –  AndrewC Dec 5 '12 at 0:56
show 4 more comments

Definitely YES.

When you move wp-config.php outside public directory you protect it from reading using browser when php handler gets maliciously (or accidentally!) changed.

Reading your DB login/password is possible when server is hardly infected through a fault of lame administrator. Charge the administrator a fine and get a better-tended and more reliable server host. Though that may be more expensive.

share|improve this answer
2  
If an attacker has enough access to change the PHP handler, you're already screwed. Accidental changes are very rare in my experience, and in that case it'd be easy to change the password. In light of those things, do you still think it's worth the risk of exposing logs/backups/etc because of the expanded open_basedir scope? –  Ian Dunn Jul 13 '12 at 18:01
1  
I've never had -rwx access to directories higher than public_html so I never was familiar with open_basedir. My logs are in separate directory, so backups do. I think that's what all shared hosts have. –  Max Yudin Jul 13 '12 at 18:35
    
Hosts vary wildly; there's no standard directory structure. Plesk (one of the most popular control panels for shared hosts) puts logs in /var/www/vhosts/example.com/statistics/logs and the document root is /var/www/vhosts/example.com/httpdocs. Moving wp-config.php to /var/www/vhosts/example.com/wp-config.php would require giving scripts access to the entire example.com directory. –  Ian Dunn Jul 14 '12 at 0:03
    
Just out of curiosity, where are your logs and backups stored, if not in the domain's directory? Are they accessed through a control panel or something? –  Ian Dunn Jul 14 '12 at 0:04
1  
Yes, through a control panel. –  Max Yudin Jul 14 '12 at 7:37
show 2 more comments

Someone asked us to shine in, and I will reply here.

Yes, there are security benefits from isolating your wp-config.php from the root directory of your site.

1- If your PHP handler gets broken or modified in some way, your DB information will not be exposed. And yes, I saw this happen a few times on shared hosts during server updates. Yes, the site will be broken during that period, but your passwords will be intact.

2- Best practices always recommend isolating configuration files from data files. Yes, it is hard to do that with WordPress (or any web app), but moving it up does a bit of isolation.

3- Remember the PHP-CGI vulnerability, where anyone could pass the ?-s to a file and view the source. http://www.kb.cert.org/vuls/id/520827

At the end, those are small details, but they do help to minimize risk. Specially if you are on a shared environment, where anyone can access your database (all they need is a user/pass).

But don't let small distractions (premature optimizations) get in front of what is really necessary to get a site properly secure:

1- Keep it always updated

2- Use strong passwords

3- Restrict access (via permissions). We have a post about it here:

http://blog.sucuri.net/2012/08/wordpress-security-cutting-through-the-bs.html

thanks,

share|improve this answer
    
Hey guys, thanks for adding your thoughts. I think we already hits on most of those points in the other answers and their comments. 1) Yes, this is possible, but rare; 2) Yes, this has benefits, but they're minimal; 3) Yes, this is possible, but that type of vulnerability is unlikely to happen again, and protecting against it is kind of like playing whac-a-mole, or making people remove their shoes at airports because some jackass hid a bomb in his shoe once. It's reactionary and unlikely to have future benefits. –  Ian Dunn Sep 12 '12 at 15:01
    
In the various discussions, the question was refined from "Are there any benefits?" to "Ok, there are some benefits, but do they outweigh the risks?" The main risk I'm referring to is the fact that you have to expand the openbase_dir scope in order to let PHP access scripts outside the web root. Many hosting setups -- including those that use Plesk, which is a lot -- store logs, backups, private FTP areas that are supposed to be isolated from the web root, etc in the directory above the web root. So, giving PHP access to that directory can be a serious vulnerability. –  Ian Dunn Sep 12 '12 at 15:04
    
Thanks for sharing your insights, Sucuri. –  Pothi Sep 18 '12 at 9:00
add comment

I just want to clarify, for the sake of argument, that moving your wp_config.php file does not necessarily mean you have to move it only to the parent directory. Let's say you have a structure like /root/html, where html contains the WP installation and all of your HTML content. Instead of moving wp_config.php to /root, you could move it to something like /root/secure ... which is both outside the html directory and also not in the server root directory. Of course, you would need to make sure that php can run in this secure folder as well.

Since WP cannot be configured to look for wp_config.php in a sibling folder like /root/secure, you have to take an additional step. I left the wp_config.php in /root/html, and cut out the sensitive portions (database login, salt, table prefix) and moved them to a separate file called config.php. Then you add the PHP include command to your wp_config.php, like this: include('/home/content/path/to/root/secure/config.php');

This is essentially what I've done in my setup. Now, based on the above discussion, I am still evaluating whether it is necessary or even a good idea. But I just wanted to add that the above configuration is possible. It does not expose your backups and other root files, and so long as the secure folder is not set up with its own public URL, it is not browsable.

Furthermore, you can limit access to the secure folder by creating an .htaccess file in there with:

order deny,allow
deny from all
allow from 127.0.0.1
share|improve this answer
    
Hey Michael, thanks for sharing that. Have you tried it out in a real environment to verify it works, though? I think the open_basedir directive takes an entire tree, so in order to access /root/secure from /root/html, you'd have to set open_basedir to /root. –  Ian Dunn Oct 3 '12 at 14:52
    
In order to make your idea work, I think you'd need to setup the directory structure like /root/httpdocs/config/accessible, where httpdocs holds logs, backups, etc; config holds wp-config.php, and accessible holds WordPress and all content. You'd have to modify the vhost config, etc to remap the document root to accessible. I don't see any benefit over just denying HTTP requests to wp-config in the default setup, though. –  Ian Dunn Oct 3 '12 at 14:53
1  
According to php.net/manual/en/ini.core.php#ini.open-basedir: "Under Windows, separate the directories with a semicolon. On all other systems, separate the directories with a colon. As an Apache module, open_basedir paths from parent directories are now automatically inherited." So you can set multiple directories, no need for them to be in a single tree. –  Michael Oct 3 '12 at 19:34
    
I just tested that out and it looks like you're right. I'm still not sure what security benefit this has over simply denying access to the file via Apache, though. –  Ian Dunn Oct 3 '12 at 22:05
    
@IanDunn addressed well in Aaron Adams' answer –  AndrewC Dec 5 '12 at 1:02
show 1 more comment

There are a lot of bad written themes and plugins out there which allow atatckers to inject code (remember the security issue with Timthumb). If I would be a attacker, why should I search for the wp-config.php? Simply inject this code:

var_dump( DB_NAME, DB_USER, DB_PASSWORD );

You can try to hide your wp-config.php. As long as WordPress make all the sensitive information global accessible, it have no benefit to hide the wp-config.php.

The bad part in wp-config.php is not that it holds sensitive data. The bad part is to define the sensitive data as a global accessible constant.

Update

I want to clearify the problems with define() and why it is a bad idea to define sensitive data as a global constant.

There are a lot of ways to attack a website. Script injection is only one way to atack a website.

Assuming the server has a vulnerability that let an attacker access a memory dump. The attacker will find in the memory dump all values of all variables. If you define a global accessible constant, it have to stay in memory until the script ended. Creating a variable instead of a constant, there is a good chance that the garbage collector will overwrite (or free) the memory after the variable is not longer needed.

A better way to protect sensitive data is to delete them immediately after using it:

$db_con = new stdClass();
$db_con->db_user = 'username';
$db_con->password = 'password';
$db_con->host = 'localhost';

$db_handler = new Database_Handler( $db_con );

$db_con = null;

After using the sensitive data, the assigning to null will overwrite the data in memory. An attacker have to get the memory dump just in the moment when $db_con contains the sensitive data. And that is a very short time in the example above (if the class Database_Handler do not save a copy of it).

share|improve this answer
    
This response does not directly address the question. Any plugin author can have a field day with WordPress if they convince you to install their code and have malicious intent. It is no different than willingly installing a virus on your system. This argument to not move wp-config.php is pointless. This is like saying that willfully installing a car bomb in your car makes setting the car alarm useless. Technically true but WTF?!? –  Charleston Software Associates Dec 6 '12 at 5:51
    
No, it is not pointless. The question is: Can I protect the database account by hiding the wp-config.php. And the answer is clearly: No. It is the same as if you ask 'Can I protect my car against car bombs with a car alarm?' There is no other benefit by hiding your wp-config as of protecting database access or ftp access. Both are in the global scope. I'm sure there are more ways for attackers to get access to global vars without injecting code. –  Ralf912 Dec 6 '12 at 7:51
    
I don't see "can I protect the database account by hiding the wp-config.php" in the original question. The original question was "does it makes sense to move the wp-config.php". The answer is absolutely yes, IMO. It is like asking if you should lock your front door when you go out. Saying "someone can easily break a window and get in anyway, so why bother" does not answer the fundamental point of the question. IMO the question asked was this, "Is it worth the extra effort to move wp-config.php? ANY benefit doing so?". Yes. At the very least it keeps out the lazy hackers. –  Charleston Software Associates Dec 10 '12 at 15:28
    
One of the most common security best practices... You missed a very (very, very) important point: To what an attacker is interested? And it is not how do you styled your wp-config.php. An attacker is interessted in the values you defined in your wp-config. Grabbing your example with the front door: Hiding your wp-config is the same as if you will lock your front door, but store all your gold unprotected in the garden. All values defined in the wp-config are globally defined. So they are all accessible outside of wp-config. Even if you hide your wp-config, the values are still present. –  Ralf912 Dec 11 '12 at 11:21
    
I think those that argue in favor of moving it are trying to protect against scenarios where wp-config.php could be displayed in plain text via an HTTP request, rather than scenarios where it could be exposed to other PHP code running on the host. –  Ian Dunn Dec 11 '12 at 22:40
show 1 more comment

Apart from the security benefits, it also allows you to keep your WordPress instance under version control while keeping the core WordPress files as a submodule/external. This is how Mark Jaquith has setup his WordPress-Skeleton project. See https://github.com/markjaquith/WordPress-Skeleton#assumptions for details.

share|improve this answer
5  
He has it setup in the document root, not outside of it, so it's not relevant to this question. The technique that the question asked about specifies that you move wp-config.php one directory above the vhost's document root, not just one directory above the WordPress installation folder. The whole point is to get it outside of the folder that can be read by HTTP requests. –  Ian Dunn Jul 17 '12 at 22:59
add comment

protected by Community Jan 29 '13 at 7:25

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.