Harden WordPress Permissions
Harden WordPress
chown [username]:www-data
find /var/www/html/DOMAIN -type d -exec chmod 755 {} \;
find /var/www/html/DOMAIN -type f -exec chmod 644 {} \;
chmod 440 /var/www/html/DOMAIN/*.php
chmod 450 -R /var/www/html/DOMAIN/wp-admin
chmod 450 -R /var/www/html/DOMAIN/wp-includes
chmod 440 /var/www/html/DOMAIN/.htaccess
chmod 766 /var/www/html/DOMAIN/sitemap.*
chmod 770 -R /var/www/html/DOMAIN/wp-content/uploads
chmod 770 -R /var/www/html/DOMAIN/wp-content/upgrade
chmod 750 -R /var/www/html/DOMAIN/wp-content/plugins
(You could put all that in a script for convenience – I have the entire code at the bottom of the page)
This is very strong security that is derived from the WordPress Codex, then enhanced until WordPress won’t work, then backed off. You may have some odd plugin behavior to deal with, usually due to the 450 on some directories. And your particular LAMP setup will determine where you need to loosen up permissions some.
Derived from WordPress Codex
http://codex.wordpress.org/Changing_File_Permissions
4 – R – Read – Allowed to read files
2 – W – Write – Allowed to write/modify files
1 – X – eXecute – Read/write/delete/modify/directory
Problems with WordPress Permissions?
Here is some explanations as to what is going on in WordPress and how and why you can change permissions.
All files should be owned and writable by your user account.
chown username:www-data
- Any file that needs write access from WordPress should be owned or group-owned by the user account used by WordPress.
- Any file that needs write access from WordPress should be group-owned by the web server; usually www-data
The root / WordPress directory and files should be writable only by your user account, except .htaccess and sitemap.* if you want WordPress to automatically update those files for you. I do not let WordPress rewrite .htaccess after its been hardened. So beware installing any plugins that require write access to .htaccess will complain. You can manually (temporarily) make .htaccess writable (make a backup).
- WordPress /wp-admin administration directory and files should be writable only by your user account.
- WordPress /wp-includes application directory and files should be writable only by your user account.
User content /wp-content is intended to be completely writable by all owner/user, group, and public. But there are some files prone to hacks that I harden. For example all index.php may be set to 440. But plan on some experimentation as the only way to be sure regarding any hardening of /wp-content
chmod 440 /var/www/DOMAIN/wp-content/index.php
If WordPress is running as the FTP account, that account needs to have write access, i.e., be the owner of the files, or belong to a group that has write access. In the latter case, that would mean permissions are set more permissively than default (for example, 775 rather than 755 for folders, and 664 instead of 644). All files should be owned by your user (ftp) account on your web server, and should be writable by that account. On shared hosts, files should never be owned by the webserver process itself (sometimes this is www, or apache, or nobody)
FTP is the weak link in WordPress security
I do not run FTP on my servers and instead use Rsync. How to install Rsync on Ubuntu Its more work maintaining Worpress this way, but compared to the work involved in recovering from a hack, its nothing (or well worth the hassle).
Shell script to Harden a WordPress Instance
#!/bin/bash DOMAIN=$1 echo "CHOWN entire site" chown -R -f username:www-data /var/www/$DOMAIN echo "securing the entire site $DOMAIN" find /var/www/$DOMAIN -type d -exec chmod 755 {} \; find /var/www/$DOMAIN -type f -exec chmod 644 {} \; chmod 440 /var/www/$DOMAIN/*.php # verified minimum OK with WP find /var/www/$DOMAIN/wp-admin -type f -exec chmod 640 {} \; find /var/www/$DOMAIN/wp-includes -type f -exec chmod 640 {} \; chmod 440 /var/www/$DOMAIN/.htaccess chmod 766 /var/www/$DOMAIN/sitemap.* chown -R -f www-data:www-data /var/www/$DOMAIN/wp-content/uploads chmod 777 -R /var/www/$DOMAIN/wp-content/uploads find /var/www/$DOMAIN/wp-content/uploads -type f -exec chmod 660 {} \; chmod 770 -R /var/www/$DOMAIN/wp-content/upgrade chmod 750 -R /var/www/$DOMAIN/wp-content/plugins find /var/www/$DOMAIN -name 'index.php' -exec chmod 440 {} \; echo "Done"