399

I've had a look over here but didn't find any details on the best file permissions. I also took a look at some of WordPress's form's questions over here too but anybody that suggests 777 obviously needs a little lesson in security.

In short my question is this. What permissions should I have for the following:

  1. root folder storing all the WordPress content
  2. wp-admin
  3. wp-content
  4. wp-includes

and then all the files in each of those folders?

Craig
  • 1,872
  • 5
  • 23
  • 56
John Crawford
  • 9,656
  • 9
  • 31
  • 42
  • Basically, only Wordpress uploads folder should be 777 but it would be a serious security threat. If you use a server with Suphp enabled, there is no need to modify permissions, manually. – Ali F Mar 29 '16 at 15:31
  • 4
    I'm voting to close this question as off-topic because it is off-topic per the tag wiki excerpt: "Off-topic questions include those about theme development, WordPress administration, management best practices, server configuration, etc" – Adriaan Jun 17 '19 at 19:47

15 Answers15

497

When you setup WP you (the webserver) may need write access to the files. So the access rights may need to be loose.

chown www-data:www-data  -R * # Let Apache be owner
find . -type d -exec chmod 755 {} \;  # Change directory permissions rwxr-xr-x
find . -type f -exec chmod 644 {} \;  # Change file permissions rw-r--r--

After the setup you should tighten the access rights, according to Hardening WordPress all files except for wp-content should be writable by your user account only. wp-content must be writable by www-data too.

chown <username>:<username>  -R * # Let your useraccount be owner
chown www-data:www-data wp-content # Let apache be owner of wp-content

Maybe you want to change the contents in wp-content later on. In this case you could

  • temporarily change to the user to www-data with su,
  • give wp-content group write access 775 and join the group www-data or
  • give your user the access rights to the folder using ACLs.

Whatever you do, make sure the files have rw permissions for www-data.

Raman Sahasi
  • 30,180
  • 9
  • 58
  • 71
ManuelSchneid3r
  • 15,850
  • 12
  • 65
  • 103
  • Plausible, if wp really only needs wpcontent. Do you have any references to substabtiate your thesis? This is SO not just chit-chat. Until now your comment is just a rant. – ManuelSchneid3r Oct 19 '14 at 11:50
  • 2
    Kornel gives one such authoritative link below. See also http://codex.wordpress.org/Changing_File_Permissions, Apache's doc http://httpd.apache.org/docs/2.2/misc/security_tips.html, and pretty much any google search on the topic. But in the general case, when in doubt, give no write access (and certainly no ownership) and loosen on a case-by-case basis, not the opposite (principle of least privilege which you're violating here). – Calimo Oct 19 '14 at 12:49
  • I agree to the approach here. A permission set for "installation/upgrading" and a "hardened permission" set seems to be the best way to ensure both ease of upgrade, while providing security in an acceptable form. – Christopher Bonitz Apr 02 '16 at 12:06
  • 22
    Why is there an auto-update feature if it doesn't even work without changing the permissions?? – malhal May 14 '16 at 19:31
  • 6
    @ManuelSchneid3r, I see some PHP files under wp-content, are these really supposed to be writable by `www-data`??? That really sounds totally not secure at all. – Alexis Wilke Aug 30 '16 at 07:35
  • 1
    Perfect solution! – Angelo Silva Sep 22 '16 at 20:08
  • 1
    @AlexisWilke If you want WP to be able to self-update, then yes. If you want tighter permissions you can set that, but you'll need to update everything manually via ftp. – DarkNeuron Oct 25 '16 at 09:40
  • I think its important to set read-only access to `wp-config.php` and possibly also `.htaccess` files. `chmod 444 wp-config.php` and possibly also `chmod 444 .htaccess` – kimbaudi Dec 16 '16 at 02:42
  • A quick note: on my server, setting 755 permissions on a dir allowed directory listing to the world. Be careful with that. To prevent directory listing, you can use 751 instead. – coccoinomane Jan 03 '17 at 16:28
  • 12
    This solution will prevent wordpress from installing 'automatic security updates'. You need to manually run the steps above for each minor wordpress update. – Jeroen Ooms Jan 13 '17 at 10:49
  • 1
    for the mac os user group is _www instead of www-data – ashishyadaveee11 Sep 08 '17 at 13:09
  • 1
    `su www-data` will not work, you can not change role to this system user by design. – d.raev Nov 23 '17 at 13:01
  • 11
    This is not a secure configuration. Setting read permissions on these files has no affect when the apache user also owns the files! DO NOT USE. Refer to https://codex.wordpress.org/Changing_File_Permissions – PodTech.io Nov 30 '17 at 10:40
  • On some hosting services, the server runs with the account owner's credentials and there's no way around it. No "www-data", no "nobody", no "apache", just user:user. If that's your case, you'll want to chmod all files to 0444 and folders to 0555 (yes, removing your own write permissions), save for the uploads folder, and only unlock them when you perform an update. – Sinus the Tentacular Aug 21 '19 at 16:25
  • what about wp-content/uploads folder? after tighten the access rights can't upload image from admin panel. – kemalatila Nov 15 '19 at 11:33
60

Giving the full access to all wp files to www-data user (which is in this case the web server user) can be dangerous. So rather do NOT do this:

chown www-data:www-data -R *

It can be useful however in the moment when you're installing or upgrading WordPress and its plug-ins. But when you finished it's no longer a good idea to keep wp files owned by the web server.

It basically allows the web server to put or overwrite any file in your website. This means that there is a possibility to take over your site if someone manage to use the web server (or a security hole in some .php script) to put some files in your website.

To protect your site against such an attack you should to the following:

All files should be owned by your user account, and should be writable by you. Any file that needs write access from WordPress should be writable by the web server, if your hosting set up requires it, that may mean those files need to be group-owned by the user account used by the web server process.

/

The root WordPress directory: all files should be writable only by your user account, except .htaccess if you want WordPress to automatically generate rewrite rules for you.

/wp-admin/

The WordPress administration area: all files should be writable only by your user account.

/wp-includes/

The bulk of WordPress application logic: all files should be writable only by your user account.

/wp-content/

User-supplied content: intended to be writable by your user account and the web server process.

Within /wp-content/ you will find:

/wp-content/themes/

Theme files. If you want to use the built-in theme editor, all files need to be writable by the web server process. If you do not want to use the built-in theme editor, all files can be writable only by your user account.

/wp-content/plugins/

Plugin files: all files should be writable only by your user account.

Other directories that may be present with /wp-content/ should be documented by whichever plugin or theme requires them. Permissions may vary.

Source and additional information: http://codex.wordpress.org/Hardening_WordPress

Calimo
  • 7,510
  • 4
  • 39
  • 61
Kornel
  • 4,184
  • 4
  • 28
  • 30
  • *by your user account.* means the user executing the php scripts on the site (Normally the apache user) ? – shasi kanth Mar 27 '15 at 11:03
  • 4
    @shasikanth No, the apache user is the one he refers to as “web server process”. User account is your Linux user (ssh, ftp user, etc.) – Daniel Bang Jul 02 '15 at 17:49
  • In this answer and in the accepted answer, should the user (not www-data) be part of the www-data group? – user658182 Mar 15 '17 at 14:20
  • 1
    Nope, that is the whole point. – Piotr Nawrot Dec 14 '17 at 07:42
  • 1
    The problem I experience is anytime I make my SSH "user" the owner of /wp-content/plugins/, Wordpress becomes completely unfunctional from within the admin, with the constant FTP pop-up routine or permissions errors. Cannot add, nor update plugins. Only when I make www-data the owner of wp-content, does the Wordpress Admin plugin functionality work. (Example: sudo chown www-data:www-data -R /var/www/html/wp-content/) – Heres2u Oct 18 '18 at 16:38
  • @Heres2u: You could (temporarily) define FTP_USER, FTP_PASS, FTP_HOST in wp-config.php and WP will stop asking. – Herbert Van-Vliet Oct 19 '18 at 15:07
  • I'd like to reference the answer I provided here as an addition to this: https://stackoverflow.com/questions/17922644/wordpress-asking-for-my-ftp-credentials-to-install-plugins - it seems the file system checks WordPress undertakes when uploading plugins (for example) is leaning us towards having the same principal own the application files & run the php process. Thoughts? – Matt Woodward Nov 07 '18 at 00:23
26

For those who have their wordpress root folder under their home folder:

** Ubuntu/apache

  1. Add your user to www-data group:

CREDIT Granting write permissions to www-data group

You want to call usermod on your user. So that would be:

sudo usermod -aG www-data yourUserName

** Assuming www-data group exists

  1. Check your user is in www-data group:

    groups yourUserName

You should get something like:

youUserName : youUserGroupName www-data

** youUserGroupName is usually similar to you user name

  1. Recursively change group ownership of the wp-content folder keeping your user ownership

    chown yourUserName:www-data -R youWebSiteFolder/wp-content/*

  2. Change directory to youWebSiteFolder/wp-content/

    cd youWebSiteFolder/wp-content

  3. Recursively change group permissions of the folders and sub-folders to enable write permissions:

    find . -type d -exec chmod -R 775 {} \;

** mode of `/home/yourUserName/youWebSiteFolder/wp-content/' changed from 0755 (rwxr-xr-x) to 0775 (rwxrwxr-x)

  1. Recursively change group permissions of the files and sub-files to enable write permissions:

    find . -type f -exec chmod -R 664 {} \;

The result should look something like:

WAS:
-rw-r--r--  1 yourUserName www-data  7192 Oct  4 00:03 filename.html
CHANGED TO:
-rw-rw-r--  1 yourUserName www-data  7192 Oct  4 00:03 filename.html

Equivalent to:

chmod -R ug+rw foldername

Permissions will be like 664 for files or 775 for directories.

P.s. if anyone encounters error 'could not create directory' when updating a plugin, do:
server@user:~/domainame.com$ sudo chown username:www-data -R wp-content
when you are at the root of your domain.
Assuming: wp-config.php has
FTP credentials on LocalHost
define('FS_METHOD','direct');

Community
  • 1
  • 1
Jadeye
  • 3,551
  • 4
  • 47
  • 63
  • 10
    -1. You do *NOT* want www-data to have write access to the wordpress files, except in wp-content. – Calimo Oct 18 '14 at 16:02
  • 775 in wp-content does help. With 644 for files, 755 for folders, and chown user:www-data, I was sometimes still having problems with media upload, plugin update, etc. 775 allows wp-content to be altered by www-data:www-data as well, which solves the problem. – guylabbe.ca Dec 12 '16 at 16:26
  • Remove the -R from the find/chmod command as it's slow and unnecessary. – Adam Jimenez Mar 27 '19 at 11:08
20

Best to read the wordpress documentation on this https://wordpress.org/support/article/changing-file-permissions/

  • All files should be owned by the actual user's account, not the user account used for the httpd process
  • Group ownership is irrelevant, unless there's specific group requirements for the web-server process permissions checking. This is not usually the case.
  • All directories should be 755 or 750.
  • All files should be 644 or 640. Exception: wp-config.php should be 440 or 400 to prevent other users on the server from reading it.
  • No directories should ever be given 777, even upload directories. Since the php process is running as the owner of the files, it gets the owners permissions and can write to even a 755 directory.
malhal
  • 26,330
  • 7
  • 115
  • 133
PodTech.io
  • 4,874
  • 41
  • 24
  • 4
    Not sure why you got down-voted: it's almost as if people want the top answer to be how to leave the installation _insecure_! – BCran Dec 27 '17 at 18:21
  • Link is outdated. new one here: https://wordpress.org/support/article/changing-file-permissions/ And thanks for being the only one referencing the actual docs! – everyman Sep 13 '19 at 08:28
  • If the wp-config.php is 400, how is the apache supposed to include it (thus read it) on page load? – Martin Braun Feb 11 '20 at 16:49
14

I set permissions to:

    # Set all files and directories user and group to wp-user
    chown wp-user:wp-user -R *

    # Set uploads folder user and group to www-data
    chown www-data:www-data -R wp-content/uploads/

    # Set all directories permissions to 755
    find . -type d -exec chmod 755 {} \;

    # Set all files permissions to 644
    find . -type f -exec chmod 644 {} \;

In my case I created a specific user for WordPress which is different from the apache default user that prevent access from the web to those files owned by that user.

Then it gives permission to apache user to handle the upload folder and finally set secure enough file and folder permissions.

EDITED

If you're using W3C Total Cache you should do the next also:

rm -rf wp-content/cache/config
rm -rf wp-content/cache/object
rm -rf wp-content/cache/db
rm -rf wp-content/cache/minify
rm -rf wp-content/cache/page_enhanced

Then it'll work!

EDITED

After a while developing WordPress sites I'd recommend different file permissions per environment:

In production, I wouldn't give access to users to modify the filesystem, I'll only allow them to upload resources and give access to some plugins specific folders to do backups, etc. But managing projects under Git and using deploy keys on the server, it isn't good update plugins on staging nor production. I leave here the production file setup:

# Set uploads folder user and group to www-data
chown www-data:www-data -R wp-content/uploads/

www-data:www-data = apache or nginx user and group

Staging will share the same production permissions as it should be a clone of it.

Finally, development environment will have access to update plugins, translations, everything...

# Set uploads folder user and group to www-data
chown www-data:www-data -R wp-content/

# Set uploads folder user and group to www-data
chown your-user:root-group -R wp-content/themes

# Set uploads folder user and group to www-data
chown your-user:root-group -R wp-content/plugins/your-plugin

www-data:www-data = apache or nginx user and group your-user:root-group = your current user and the root group

These permissions will give you access to develop under themes and your-plugin folder without asking permission. The rest of the content will be owned by the Apache or Nginx user to allow WP to manage the filesystem.

Before creating a git repo first run these commands:

# Set all directories permissions to 755
find . -type d -exec chmod 755 {} \;

# Set all files permissions to 644
find . -type f -exec chmod 644 {} \;
tobybot
  • 516
  • 5
  • 15
Pablo Ezequiel Leone
  • 1,337
  • 17
  • 22
  • 11
    Nooo! Never do a 777. Please don't advice this to (new) people reading this. – Karel Sep 10 '18 at 11:47
  • NO files or folders should be owned by the http process - this is a major security gap. If a malicious user found an exploit in a plugin or theme or wordpress itself they could upload code that can then be run by apache and gain access - i have seen it first hand :( – DropHit Aug 17 '19 at 18:57
10

Correct permissions for the file is 644 Correct permissions for the folder is 755

To change the permissions , use terminal and following commands.

find foldername -type d -exec chmod 755 {} \;
find foldername -type f -exec chmod 644 {} \;

755 for folders and 644 for files.

Kappa
  • 1,015
  • 1
  • 16
  • 31
  • 1
    and 640 for wp-config.php.But unfortunately, you have to change uploads&plugins&themes folders' permissions to 775 and if you wanna upgrade your wordpress then you have to change all folders to 775.In this section your permissions will pop up errors while upgrading/changing plugins,themes and uploading medias. – erginduran May 01 '17 at 09:20
8

I think the below rules are recommended for a default wordpress site:

  • For folders inside wp-content, set 0755 permissions:

    chmod -R 0755 plugins

    chmod -R 0755 uploads

    chmod -R 0755 upgrade

  • Let apache user be the owner for the above directories of wp-content:

    chown apache uploads

    chown apache upgrade

    chown apache plugins

shasi kanth
  • 6,987
  • 24
  • 106
  • 158
  • 1
    You can also recursively set permissions for the directories, like: **chown -R apache uploads**. And if required, you can also give the group ownership to apache: **chgrp apache uploads** – shasi kanth Jun 25 '15 at 09:29
8

It actually depends on the plugins you plan to use as some plugins change the root document of the wordpress. but generally I recommend something like this for the wordpress directory.

This will assign the "root" (or whatever the user you are using) as the user in every single file/folder, R means recursive, so it just doesn't stop at the "html" folder. if you didn't use R, then it only applicable to the "html" directory.

sudo chown -R root:www-data /var/www/html  

This will set the owner/group of "wp-content" to "www-data" and thus allowing the web server to install the plugins through the admin panel.

chown -R www-data:www-data /var/www/html/wp-content

This will set the permission of every single file in "html" folder (Including files in subdirectories) to 644, so outside people can't execute any file, modify any file, group can't execute any file, modify any file and only the user is allowed to modify/read files, but still even the user can't execute any file. This is important because it prevents any kind of execution in "html" folder, also since the owner of the html folder and all other folders except the wp-content folder are "root" (or your user), the www-data can't modify any file outside of the wp-content folder, so even if there is any vulnerability in the web server, and if someone accessed to the site unauthorizedly, they can't delete the main site except the plugins.

sudo find /var/www/html -type f -exec chmod 644 {} +

This will restrict the permission of accessing to "wp-config.php" to user/group with rw-r----- these permissions.

chmod 640 /var/www/html/wp-config.php

And if a plugin or update complained it can't update, then access to the SSH and use this command, and grant the temporary permission to "www-data" (web server) to update/install through the admin panel, and then revert back to the "root" or your user once it's completed.

chown -R www-data /var/www/html

And in Nginx (same procedure for the apache)to protect the wp-admin folder from unauthorized accessing, and probing. apache2-utils is required for encrypting the password even if you have nginx installed, omit c if you plan to add more users to the same file.

sudo apt-get install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd userName

Now visit this location

/etc/nginx/sites-available/

Use this codes to protect "wp-admin" folder with a password, now it will ask the password/username if you tried to access to the "wp-admin". notice, here you use the ".htpasswd" file which contains the encrypted password.

location ^~ /wp-admin {
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
    index  index.php index.html index.htm;
}

Now restart the nginx.

sudo /etc/init.d/nginx restart
Don Dilanga
  • 2,722
  • 1
  • 18
  • 20
  • Using the root user is not recommended.it could be more dangerous Just make a new user n add him to sudo group – erginduran May 01 '17 at 09:24
  • I didn't advocate here to use the root. I used the root as an example. you can use whatever any name instead of using the root. – Don Dilanga May 01 '17 at 11:13
2

Commands:

chown www-data:www-data -R *
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;

Where ftp-user is what user you are using to upload the files

chown -R ftp-user:www-data wp-content
chmod -R 775 wp-content
Juanjo Salvador
  • 1,073
  • 1
  • 12
  • 33
  • 1
    should be chown username:www-data otherwise you can't edit files – malhal Feb 02 '16 at 21:48
  • You can use `$(whoami)` instead of `ftp-user`. By default, your current user (**not root**) is your FTP user if you are using your own server (local, vps, etc) – Juanjo Salvador Jul 06 '16 at 12:22
2

To absolutely make sure that your website is secure and you are using correct permissions for your folders, use a security plugin like these:

https://en-ca.wordpress.org/plugins/all-in-one-wp-security-and-firewall/

https://en-ca.wordpress.org/plugins/wordfence/

These plugins will scan your Wordpress installation and notify you about any potential issues. These will also warn you about any insecure folder permissions. In addition to that, these plugins will recommend you what permissions should be assigned to the folders.

user296526
  • 404
  • 1
  • 3
  • 9
2
chown -Rv www-data:www-data
chmod -Rv 0755 wp-includes
chmod -Rv 0755 wp-admin/js
chmod -Rv 0755 wp-content/themes
chmod -Rv 0755 wp-content/plugins
chmod -Rv 0755 wp-admin
chmod -Rv 0755 wp-content
chmod -v 0644 wp-config.php
chmod -v 0644 wp-admin/index.php
chmod -v 0644 .htaccess
Grapehand
  • 19
  • 5
1

I can't tell you whether or not this is correct, but I am using a Bitnami image over Google Compute App Engine. I has having problems with plugins and migration, and after further messing things up by chmod'ing permissions, I found these three lines which solved all my problems. Not sure if it's the proper way but worked for me.

sudo chown -R bitnami:daemon /opt/bitnami/apps/wordpress/htdocs/
sudo find /opt/bitnami/apps/wordpress/htdocs/ -type f -exec chmod 664 {} \;
sudo find /opt/bitnami/apps/wordpress/htdocs/ -type d -exec chmod 775 {} \;
wayofthefuture
  • 8,339
  • 7
  • 36
  • 53
1

For OS X use this command:

sudo chown -R www:www /www/folder_name
Abduhafiz
  • 3,318
  • 5
  • 38
  • 48
1

Define in wp_config file.

/var/www/html/Your-Project-File/wp-config.php

define( 'FS_METHOD', 'direct' );

chown - changes ownership of files/dirs. Ie. owner of the file/dir changes to the specified one, but it doesn't modify permissions.

sudo chown -R www-data:www-data /var/www
Harish Verma
  • 548
  • 7
  • 17
0

Based on all the reading and agonizing on my own sites and after having been hacked I have come up with the above list that includes permissions for a security plugin for Wordpress called Wordfence. (Not affiliated with it)

In our example, the wordpress document root is /var/www/html/example.com/public_html

Open up the permissions so that www-data can write to the document root as follows:

cd /var/www/html/example.com
sudo chown -R www-data:www-data public_html/

Now from the dashboard in your site, as an admin you can perform updates.

Secure Site after Updates are finished by following these steps:

sudo chown -R wp-user:wp-user public_html/

The above command changes permissions of everything in the wordpress install to the wordpress FTP user.

cd public_html/wp-content
sudo chown -R www-data:wp-user wflogs
sudo chown -R www-data:wp-user uploads

The above command ensures that the security plugin Wordfence has access to its logs. The uploads directory is also writeable by www-data.

cd plugins
sudo chown -R www-data:wp-user wordfence/

The above command also ensures that the security plugin has required read write access for its proper function.

Directory and Files Permissions

# Set all directories permissions to 755
find . -type d -exec chmod 755 {} \;

# Set all files permissions to 644
find . -type f -exec chmod 644 {} \;

Set the permissions for wp-config.php to 640 so that only wp-user can read this file and no one else. Permissions of 440 didn't work for me with above file ownership.

sudo chmod 640 wp-config.php

Wordpress automatic updates using SSH were working with fine with PHP5 but broke with PHP7.0 due to problems with php7.0-ssh2 bundeld with Ubuntu 16.04 and I couldn't find how to install the right version and make it work. Fortunately a very reliable plugin called ssh-sftp-updater-support (free) makes automatic updates using SFTP possible without need for libssh2. So the above permissions never have to be loosened except in rare cases as needed.

Zain Shaikh
  • 6,013
  • 6
  • 41
  • 66