Correct file permissions for WordPress [closed]

Solution 1:

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.

Solution 2:

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

Solution 3:

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');

Solution 4:

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.

Solution 5:

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 {} \;