note: making edits as i go

BTW, I am running my site on a Dreamhost VPS

Problem
Ok, so I have done a crap load of research on what the file and directory permissions should be for Drupal 7 and I am tired of spinning my wheels. I cannot find anything definitive or clear on what these should be because the advice usually assumes some higher level of knowledge, is not clear, assumes use of SSH, etc, or conflicts with other advice I have found.

I also want to satisfy the following related Security Review errors:

* Executable PHP in files Directory
* Some files and directories in your install are writable by the server

I, and many others, would like it very much if someone could clarify this for us:

What I have so far

Owner is my user, group is server

Below is what I have so far, but after I implement the 644 for all files I get a 403 error with the site unavailable. If I change the file permissions site-wide to 744 then the site becomes available, so I am assuming that somewhere some files in a directory somewhere needs write permissions. Where? No clue!!

I am trying to get this all figured out for my STOPs for Drupal projects, but a lack of clear documentation is a significant problem, which is especially disconcerting when it comes to a security issue.

To start:

  • (site-wide all directories) 755
  • (site-wide all files) 644

Then:

  • /.htaccess- 444 - (chosing something more restrictive and Drupal seems to work OK) (needs read public or site will get 403) Why are user write permissions needed at all?
  • /sites/default (directory) - 555 - why are execute permissions needed?
  • /sites/default/settings.php - 400 - (chosing something more restrictive and Drupal seems to work OK) Why are group and public read permissions needed?
  • /sites/default/files (directories) - 775
  • /sites/default/files (files) - 664

Please help make this crystal clear for posterity!!

Comments

FreeXenon’s picture

I found this:

/sites/files (directories) 775
/sites/files (files) 664

I will try to apply this when my current permission changes gets done applying.

FreeXenon’s picture

I also see some that mention:

  • upload
  • temp
  • private directories

Upload directory I have no idea where that is.
As for Temp and Private directories. I think what is recommended are directories that are outside your core Drupal install, but I am not sure. I have these and these paths are added in Drupal.

FreeXenon’s picture

Some also mention changing owners too?
Is it possible that the Security Review errors are triggering off this?

Do I need to change the group?
I am assuming my account as the user is fine?

FreeXenon’s picture

It turns out that the .htaccess needs public read or I get 403 errors.

settings.php set to 400 seems OK

Jaypan’s picture

sites/default/settings.php should be 444 as far as I know.

FreeXenon’s picture

That is what I have read too, but worry about hackers having easy access to the settings.php which is why I set public to 0.
Does that even make sense?

Jaypan’s picture

Yeah, it makes sense.

I thought it wouldn't work - ie your Drupal installation wouldn't work. If it works, then why not.

Jaypan’s picture

And .htaccess should be 644.

FreeXenon’s picture

Is there a specific reason why we could not go with a more restrictive 444?
Perhaps write is only needed for updates?

FreeXenon’s picture

It would be great also to explain why each permission is needed and what problems it could cause if changed to something else. Something like this would help greatly for troubleshooting permission issues too. Knowing if a more restrictive permission could be used, but changed when needed is also good information.

/.htaccess 444

  • u 4: ?? - Drupal docs says this should be a 6, why is write needed? Drupal seems to work OK without. Would we have to turn it on in certain circumstances like site updates?
  • g 4: ??
  • p 4: if public read is not available then site will return 403 errors)
FreeXenon’s picture

No one has any other comments?

koenrog’s picture

Sorry for posting in this old thread, but I ended up here as well, after being hacked by someone uploading a anonymously a php file in my files folder and compromising the box from there. The server warned me on Saturday for security updates and the hack happened on Sunday. Life goes fast ...

A link to a documentation page would be nice here ...

oscar_rockalingua’s picture

I found the official documentation for setting permissions on /sites/default/,  /sites/default/settings.php, and /sites/default/files:

https://www.drupal.org/docs/7/install/step-3-create-settingsphp-and-the-...

But can't find anything official about the rest of the folders and files of a drupal installation.

I also found this on the community docs, though it says it needs to be updated:
https://www.drupal.org/node/244924#summarizing-the-permissions

figover’s picture

all files permission 444

all directory permission 555

root 'htdocs' directory permission 555

there should be no "tmp" directory at drupal root , place tmp outside where hackers can not access with weburl

sites/default/files directory permission 775

all directories in sites/default/files 775

all files in sites/default/files 664

I hope you guys will protect website from hackers. 

Jumoke’s picture

Hi what's the suggested setting for the private folder?

Jaypan’s picture

The private folder is best set outside your webroot.

If you do a D8 install with composer, it comes with a private folder in the system root (which is one directory up from the webroot), and it is automatically configured to work with that directory. If you are working with a preinstalled private folder that is in your webroot, you should move it one directory above the webroot, then set ../ as the private files folder, in settings.php.

Nick Dewitte’s picture

Your .htaccess does not need public read access if your apache (or whatever serves your site) is a member of the group that owns that file. Isn't that a better way to deal with it?

bmateus’s picture

@figover

Thanks for this, really really helps!

But I found out that I needed to have /sites/all/modules to 755, or else I wouldn't be able to manage (update, install, uninstall) them throught the dashboard.

Anyone else with the same thing, or is it me?

Bruno Mateus

puggan’s picture

"/sites/default (directory) - 555 - why are execute permissions needed?"

Execute on a file => You are allowed to run/execute the file.
Execute on a directory => You are access the files inside it

So its the same as the global 644 for files and 755 for directories, as you want to application to be able to use the directory.

More details on StackOverflow/SupserUser:
https://superuser.com/questions/168578/why-must-a-folder-be-executable

slinky’s picture

settings.php at 400 triggers the installation when accessing Drupal as it is too restrictive. I have it set at 644.

Jaypan’s picture

At least set it at 444. 644 is insecure.

slinky’s picture

Yes - that's what I reset it as even though it conflicts with internal scripts (such as IP banning which adds the IP to the .htaccess file.) Unfortunately it appears that this file is what many bots try to hit in order to exploit vulnerabilities. Thanks for the follow up, which I think is important for other webmasters to be aware.

mmjvb’s picture

See https://www.drupal.org/node/244924. Disagree with the statement in there:

Note that in a multiple-customer hosting environment, the user-owner of the Drupal files and directories should be root.

Other than that it gives good information on setting it up correctly.

Consider the last digit anything other than 0 as insecure. Which is why it runs: 

[root@localhost]cd /path_to_drupal_installation
[root@localhost]chown -R greg:www-data .
[root@localhost]find . -type d -exec chmod u=rwx,g=rx,o= '{}' \;
[root@localhost]find . -type f -exec chmod u=rw,g=r,o= '{}' \;

The o= makes the last digit 0. 
So, you would use 640. When using the admin UI to change anything it will be set to 440 to protect you from loosing changes. You would need to acquire write access (640, u+w) to make manual changes and are warned about the fact the content has changed. This should stop you from overwriting the file with a copy maintained somewhere else.

When you are redirected to install there might be something wrong about sites/default/settings.php. The second digit should allow traversing to the default and read access on settings.php. Obviously, the information provided in settings.php must be correct related to the database connection information.

Collins405’s picture

Does anyone have a quick inline ssh command for securing everything?

Maybe something like this?

find . -type f -exec chmod 444 -- {} + && 

find . -type d -exec chmod 555 -- {} + && 

find sites -type f -exec chmod 755 -- {} + && 

find sites -type d -exec chmod 755 -- {} + && 

find . -name "settings.php" -exec chmod 444 {} + && 

find . -name "default.settings.php" -exec chmod 444 {} + && 

chmod 555 sites && 

chmod 555 sites/all && 

find sites/all -type f -exec chmod 444 -- {} + && 

find sites/all -type d -exec chmod 555 -- {} + 

/chris

sassafrass’s picture

Lynn Haas

MrSnrub’s picture

What should the permissions on the /var/www/html/profiles directory and all its subdirectories be?

Jaypan’s picture

They should be the default, 755.