☰
WEB SECURITY / PRACTICE

Secure WordPress File and Directory Permissions: A Practical Configuration Guide

Secure WordPress File and Directory Permissions: A Practical Configuration Guide

WordPress file permissions determine who can read, modify, or execute data on the server. A mistake in a single directory can allow an attacker to replace a PHP file, upload a backdoor, or read credentials from wp-config.php.

Secure permissions are not the only security control, but they are an important baseline check after installing a site, migrating it, restoring a backup, or adding plugins. The practical configuration below is suitable for a typical WordPress installation and explains when the standard values need to be changed.

What 644, 755, and 777 Permissions Mean

On Linux, permissions are written as three digits: one each for the owner, group, and other users. The value 4 means read, 2 means write, and 1 means execute. For a regular file, 644 means that the owner can read and modify the file, while the group and other users can only read it.

For a directory, execute permission means being able to enter the directory and access its contents. That is why directories usually have 755 permissions: the owner can read, modify, and browse the contents, while other users can browse the directory and open files without being able to write to them.

Permissions set to 777 grant read, write, and execute access to everyone. This is almost never justified for WordPress. If a plugin or hosting environment requires 777, first investigate the owner, group, PHP-FPM, or write-policy configuration instead of simply broadening access.

  • WordPress files: 644 by default.
  • Directories: 755 by default.
  • wp-config.php: 640 or stricter, if compatible with the server configuration.
  • Do not use 777 for files, directories, or uploads.

Recommended Permissions for a WordPress Structure

For most sites, it is sufficient to start with 644 for files and 755 for directories. This allows the web server to read the site without granting write access to every system user. However, the actual requirements depend on the hosting model: PHP may run as the site user, as the web-server user, or through a separate PHP-FPM pool.

wp-config.php contains database connection details, security keys, and other important settings. You can restrict it to 640 if the PHP process has access through the owner or group. The 600 setting is stricter, but it will work only when PHP actually runs as the file owner.

On some configurations, wp-config.php can be placed one level above the WordPress root directory. This reduces the risk of direct access to the file, but it does not replace correct permissions and web-server settings.

  • Root PHP files, .htaccess, and other service files: usually 644.
  • wp-admin, wp-includes, wp-content, and nested directories: usually 755.
  • Files in wp-content/uploads: usually 644; directories: 755.
  • Backup files, database dumps, and private keys should not be stored in a publicly accessible directory with open read access.
find /path/to/wordpress -type d -exec chmod 755 {} \;
find /path/to/wordpress -type f -exec chmod 644 {} \;
chmod 640 /path/to/wordpress/wp-config.php

Why These Commands Must Not Be Run Without Verification

In the example, replace the path with the actual site root. Do not run these commands with an incorrect path or immediately against the entire server: they could change system-file permissions and break other sites. After making changes, test the home page, administration area, media uploads, and updates if they are required.

If WordPress cannot write a file after you apply stricter permissions, do not automatically switch to 777. First check the owner, group, and permissions of the specific directory that genuinely requires write access.

Ownership and Group Matter More Than the Permission Digits

Permissions of 644 do not make a file secure if its owner or group is configured incorrectly. For example, the web-server process may have write access through its group even though the permissions appear standard. Conversely, WordPress may be unable to update files if they belong to a different system user.

A safer production model is a separate system user for each site, a restricted group, and no shared write access between different sites on the same server. File ownership should not belong to an arbitrary user under which all virtual hosts run.

After a migration, check the owner and group with the ls or stat command. Do not change ownership blindly: the web-server username differs depending on the distribution, control panel, and PHP configuration.

  • Check who owns the WordPress root and wp-content.
  • Make sure one site cannot modify another site's files.
  • Determine which user PHP-FPM or another PHP handler runs as.
  • For bulk ownership changes, use the exact path and create a backup in advance.
stat -c '%A %U:%G %n' /path/to/wordpress/wp-config.php
find /path/to/wordpress -maxdepth 2 -printf '%M %u:%g %p\n' | head -50

Special Controls for wp-content/uploads

The uploads directory is intended for images, documents, and other uploads. Users or plugins may write files there, which makes this directory a frequent target for malicious-code uploads.

Permissions of 755 alone are not enough to prevent PHP execution. They control filesystem access, while execution also depends on the configuration of Apache, Nginx, PHP-FPM, and extension-handling rules. Therefore, PHP-code execution must be separately disabled in uploads at the web-server level.

Do not store backups, database dumps, configuration files, or password-containing archives in uploads. If such files already exist, move them outside the public root or protect them with appropriate access rules.

  • Do not set wp-content/uploads to 777.
  • Disable PHP execution in the uploads directory at the web-server level.
  • Check that uploaded files cannot be opened by URL if they are meant to remain private.
  • Limit file types and sizes using WordPress, server, or WAF controls.

Important Apache and Nginx Warning

Rules for disabling PHP execution depend on the web server and its configuration. With Apache, this may be a separate rule in the directory configuration; with Nginx, it requires a correct location setup and appropriate request forwarding to PHP-FPM. An incorrect universal snippet can block all files or create a false sense of security.

Before making changes, test the configuration in a staging environment or ask a server administrator to apply a policy specifically to uploads. Then verify that normal images open correctly and that a test PHP file is not executed.

How to Check Permissions After a Migration or Restore

Migrations, archive extraction, and backup restores often change ownership or add files with excessive permissions. A plugin may also create a directory whose permissions differ from the general scheme. Check not only the site root, but also wp-content, uploads, plugins, themes, and newly created files.

To find excessive permissions, it is useful to check files and directories separately. Not every result automatically indicates a vulnerability, but 666, 775, or 777 permissions require an explanation. Pay particular attention to PHP files that did not appear as part of a planned update.

  • Find files that are writable by all users.
  • Find directories with 777 or 775 permissions and determine why they are needed.
  • Check the date, owner, and origin of new PHP files.
  • After the review, test the site, administration panel, media library, and caching.
find /path/to/wordpress -type f -perm -002 -ls
find /path/to/wordpress -type d \( -perm -002 -o -perm -020 \) -ls
find /path/to/wordpress -type f -name '*.php' -printf '%M %u:%g %TY-%Tm-%Td %p\n' | sort

Common Mistakes and a Safe Order of Operations

The most common mistake is fixing a write error with chmod -R 777. This masks an ownership or group problem while increasing the potential impact of a compromise of another account on the server.

The second mistake is setting 640 for every file without checking. Some server configurations will not be able to read the required files if PHP or the web server is not in the appropriate group. Similarly, do not blindly set every directory to 700: the site may lose access to necessary resources.

Work step by step: create a backup, record the current permissions, change one site or a staging copy, test its functions, and only then apply the changes in production. Also restrict SSH access, keep WordPress and plugins updated, use backups, and monitor file changes.

  • Do not confuse filesystem permissions with web-server rules: both layers of protection are needed.
  • Do not delete unfamiliar files without a backup and analysis.
  • Do not leave migration archives in a public directory.
  • Store separate backups outside the server and periodically test their restoration.

Frequently asked questions

Should 644 be set for all WordPress files?

It is a secure baseline for most files, but not an absolute rule. Service files may require a different scheme, while wp-config.php should generally be restricted to 640 or stricter if the server can access it.

Why does WordPress request write permissions when files are set to 644?

Most often, the PHP process does not own the files and does not have write access through the group. Check the owner, group, and PHP-FPM model. Do not solve the problem by setting permissions to 777.

Is disabling PHP in wp-content/uploads enough?

It is an important step, but not complete protection. You must also control upload types, keep WordPress and plugins updated, protect administrative access, and check files for signs of compromise.

Can wp-config.php be made accessible only to its owner?

Yes, permissions of 600 may be appropriate if PHP runs as the file owner. Check the server configuration before making the change; otherwise, WordPress will lose access to its configuration.

How often should file permissions be checked?

Always check them after a migration, backup restore, hosting change, or plugin installation or removal. For important sites, regular automated checks of files and ownership are also useful.

Conclusion

A secure baseline for WordPress is 644 for files, 755 for directories, restricted permissions for wp-config.php, and correct ownership and group settings. Give special attention to wp-content/uploads: PHP files must not be executed there, even when the directory needs to be writable.

File permissions should be reviewed together with the web-server configuration and the PHP execution model. If the site cannot update or upload media, identify the exact permissions or ownership issue instead of opening the server to everyone with 777.

← All web security materials