Short answer: the standard WordPress permissions are
755
for directories,
644
for files, and
600
(or
640
) for
wp-config.php
. You can set them three ways: SSH (fastest), SFTP from FileZilla or WinSCP (no terminal needed), or your hosting file manager (no client install). Never set anything to
777
– it is the most common cause of WordPress sites getting compromised.
Standard WordPress file permissions#
| Path | Permission | Why |
|---|---|---|
| Directories (most) |
755
| Owner can write, everyone can traverse and read |
| Files (most) |
644
| Owner can write, everyone can read |
wp-config.php
|
600
or
640
| Only owner (or owner + group) can read – protects DB credentials |
.htaccess
|
644
| Web server reads it; owner writes it |
wp-content/uploads/
|
755
| PHP writes uploads here as the web user |
wp-content/plugins/
|
755
| Plugins install/update via this directory |
wp-content/themes/
|
755
| Themes update via this directory |
wp-content/cache/
|
755
| Cache plugins write generated files here |
| Executable scripts (rare) |
755
| Only files actually executed as scripts |
If you are wondering what those numbers mean, each digit represents permissions for a user class – owner, group, and everyone else – where
7
= read+write+execute,
6
= read+write,
5
= read+execute,
4
= read-only, and
0
= no access.
755
therefore means “owner has full control; group and world can read and traverse.”
644
means “owner can read and write; group and world can only read.” That is the right baseline for almost every file in a WordPress install. For the underlying chmod and chown model in detail, see Linux file permissions: chmod and chown explained.
Why 777 is a security disaster#
A lot of “fix the problem by setting it to 777” tutorials exist on the internet. They are wrong.
777
means “any user on the server can read, modify, and execute this file.” On a shared server, that includes other customers. On any server, it includes anyone who gains a foothold through another vulnerability – a compromised plugin, a leaked SFTP credential, a misconfigured service.
The realistic consequences of
777
on WordPress files:
- Plugin malware can write into core. A vulnerable plugin running as the web user can modify any
777file, includingwp-config.phpand core PHP files. - Cross-site contamination on shared hosting. If a neighbor’s site is compromised, the attacker can pivot into your
777directories and inject backdoors. - Backdoors survive plugin removal. Malware often plants files in writable directories during the breach window.
777directories make that trivial. - Hosting providers may auto-quarantine. Many hosts detect
777permissions during malware scans and either fix them automatically or flag the account for manual review.
The correct fix is almost always to set the right user/group ownership so the web server can write where it legitimately needs to (
/wp-content/uploads
,
/wp-content/cache
,
wp-content/plugins
during updates) without making the files world-writable.
When the standard permissions are not working#
You set everything to
644
and
755
and WordPress still throws “could not write to file” errors during plugin updates, or
/wp-content/uploads
rejects new image uploads. The cause is almost always ownership, not permission bits.
The web server runs as a specific user (often
www-data
,
nginx
,
apache
, or a per-account user on managed hosts). For the web server to write to a file, the owner or group on that file must include the web user. If you uploaded files via SFTP as user
john
, those files are owned by
john:john
– the web server cannot modify them no matter what permission bits you set.
Two common shapes of this problem:
- You SFTP’d in new files and now WordPress cannot update them. The new files are owned by your SFTP user. Either change ownership to the web user (
chown www-data:www-data file) or – on managed hosting – the host’s SFTP setup is supposed to use the web user automatically. If it does not, contact support. - You manually created a directory in
wp-content/uploadsand uploads go elsewhere. Same issue. The directory is owned by you, not the web user, so PHP cannot write into it.
On Hostney, SFTP/SSH users and PHP run as the same per-account user, so files created either way are owned correctly. Most managed WordPress hosts handle this similarly. On a VPS where you installed Nginx + PHP yourself, you need to set this up explicitly – usually by adding your SFTP user to the web group, or by configuring PHP-FPM to run as the user that owns the files.
How to change permissions: three methods#
Pick based on what access you have and what you are comfortable with.
Method 1: SSH (fastest, recommended if you have shell access)#
If you can SSH into the server, three commands set every WordPress file correctly:
# Navigate to your WordPress root
cd /path/to/your/wordpress
# Set all directories to 755
find . -type d -exec chmod 755 {} \;
# Set all files to 644
find . -type f -exec chmod 644 {} \;
# Lock down wp-config.php
chmod 600 wp-config.php
This handles the common case for an entire install. If you also need to fix ownership, the equivalent is
chown -R www-data:www-data .
(replace
www-data
with whatever user your web server runs as).
For the basics of running commands over SSH, see How to set up passwordless SSH login. For background on user-level chmod, How to change a user password in Linux covers the same authentication model.
Method 2: SFTP client (no terminal needed)#
If you do not have SSH or prefer a GUI, every SFTP client supports changing permissions.
FileZilla:
- Connect to your site over SFTP (not plain FTP – SFTP is encrypted and standard on modern hosts).
- Navigate to the file or directory.
- Right-click and select “File permissions” (or “File attributes” on older versions).
- Enter the numeric value (e.g.
644) or tick the boxes. The dialog shows you the resulting number as you tick. - For directories, tick “Recurse into subdirectories” and choose “Apply to files only” or “Apply to directories only” so you can apply
644to files and755to directories in two passes.
WinSCP (Windows) and Cyberduck (Mac) work the same way – find the file, right-click, set permissions.
The “two passes” approach matters: applying
755
recursively to everything makes every file executable (which is wrong), and applying
644
recursively to everything makes directories unreadable (which is worse – the site stops loading entirely). Always separate “files only” and “directories only” when recursing.
For more on SFTP versus the older FTP and FTPS protocols, see SFTP vs FTP vs FTPS: which should you use. For the underlying protocol, What is SFTP and how does it work covers the basics.
Method 3: Hostney file manager (no SSH, no SFTP client)#
If you are on Hostney, the built-in file manager in your control panel handles permissions without needing SSH access or an SFTP client installed on your machine. This is the right path when:
- You are on a locked-down machine where you cannot install FileZilla.
- You need to fix permissions on a single file or directory quickly without setting up SSH keys.
- You are helping a non-technical client and walking them through the steps live.
- The site is locked out and wp-admin is unavailable – the hosting control panel still works.
To change permissions in the Hostney file manager:
- Log in to your Hostney control panel.
- Open the file manager for the site.
- Navigate to the file or directory.
- Right-click the entry and select “Change permissions” (or use the toolbar action).
- Enter the numeric value (
644,755,600) or tick the read/write/execute boxes for owner, group, and world. - For directories, the dialog includes a recurse option so you can apply the change to everything inside.
The Hostney file manager runs server-side as the account’s web user, so any file you create or modify through it has the correct ownership automatically – the “I SFTP’d files in and now PHP cannot write to them” problem does not happen.
For the broader case of managing files without an FTP client at all, WordPress file manager: managing files without FTP covers all four realistic options (control panel, SFTP, SSH, plugin) and when each is right.
The FS_METHOD setting and why it matters#
WordPress decides how to write files – for plugin installs, theme updates, and core updates – using a setting called
FS_METHOD
in
wp-config.php
. If this setting is wrong, even correct permissions will not stop WordPress from prompting for FTP credentials during updates or refusing to update at all.
The values WordPress understands:
| Value | What it does |
|---|---|
direct
| Write files directly using PHP. Requires the web user to own the files. Recommended on most hosts. |
ssh2
| Use the SSH2 PHP extension. Rare; needs
pecl ssh2
installed. |
ftpext
| Use the FTP extension. Forces WordPress to prompt for FTP credentials. |
ftpsockets
| Use FTP sockets. Same as
ftpext
for end-user purposes. |
On most managed hosts (including Hostney), the right value is
direct
. WordPress detects this automatically when the web user owns the WordPress files. If detection fails – usually because of mixed ownership – WordPress falls back to prompting for FTP credentials, which feels broken even though permissions are technically correct.
To force the right behavior, add this to
wp-config.php
above the
/<em> That's all, stop editing! </em>/
line:
define('FS_METHOD', 'direct');
If you see WordPress asking for FTP credentials during a plugin install on a host where you do not even have FTP set up, this is almost always the fix. See wp-config.php explained: what every setting does for the full list of constants and what each controls.
Common problems and what they mean#
| Symptom | Most likely cause | Fix |
|---|---|---|
| “Installation failed: Could not create directory” during plugin install |
wp-content/plugins/
not writable by web user |
chmod 755 wp-content/plugins/
+ fix ownership if SFTP user differs from web user |
| Uploads return “Failed to write to disk” or 0-byte files |
wp-content/uploads/
not writable or wrong owner |
chmod 755 wp-content/uploads/
+ check ownership |
| WordPress asks for FTP credentials on plugin install |
FS_METHOD
not set, files have mixed ownership | Add
define('FS_METHOD', 'direct');
to
wp-config.php
|
| 500 Internal Server Error after permission change | A directory was set to
644
(unreadable) or a file was set to
000
| Restore directories to
755
and files to
644
|
| 403 Forbidden on the whole site | The web root or one of its parents has wrong permissions or owner | Check the parent directory permissions and ownership chain (see WordPress 403 Forbidden error: how to fix it) |
.htaccess
rewrites stopped working |
.htaccess
set to non-readable mode |
chmod 644 .htaccess
|
wp-config.php
editable by other users on shared hosting | Permission too loose (
644
or
666
) |
chmod 600 wp-config.php
(or
640
if web user is in your group) |
| Malware keeps reappearing after cleanup | Writable directories let attacker re-implant; permissions are masking the original entry point | Fix permissions, then audit for the original vulnerability (see WordPress malware: how it gets in and how to remove it) |
When permissions are not the real problem#
A surprising number of “permission” issues are not permission issues. Before spending hours on
chmod
, check:
- Disk full. If the partition is out of space, writes fail with errors that look like permission failures.
df -hconfirms. - PHP
open_basedirrestriction. PHP can be limited to specific directory trees by the host. Files outside that tree are unreachable even with777. - SELinux or AppArmor on the server. Mandatory access control can block writes that traditional permissions would allow.
getenforce(SELinux) oraa-status(AppArmor) shows the current state. - Mounted read-only filesystem. Less common, but a misconfigured mount can put
wp-contenton a read-only volume. - Plugin-level write checks. Some security plugins block PHP from writing to specific paths regardless of OS-level permissions.
If
chmod
does not fix the symptom and ownership looks right, one of these is the real cause.
Recovering from a permission disaster#
If you have already run a bad recursive
chmod
(e.g.
chmod -R 777 .
or
chmod -R 644 .
which makes directories unreadable), restore the standard layout in two commands:
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
chmod 600 wp-config.php
This handles the vast majority of cases. The site comes back online immediately for permission-related 500s and 403s. If ownership was also wrong (you ran the commands as
root
and now everything is owned by
root
), follow with:
chown -R www-data:www-data . # or whatever your web user is
chmod 600 wp-config.php
After this, plugin installs and uploads should work normally. If you are unsure what the web user is on your host, your hosting control panel or support team can confirm. On Hostney, every account has its own dedicated Linux user that owns all files and runs PHP – there is no shared
www-data
.
Quick reference#
- Directories:
755 - Files:
644 -
wp-config.php:600or640 - Never use
777 - Ownership matters as much as permission bits
- Set
FS_METHODtodirectinwp-config.phpif WordPress asks for FTP credentials on a host where you have no FTP set up - When everything breaks, run the
findcommands above to restore standard permissions
For the broader security picture – permissions are one layer among many – see Is WordPress secure, and how to harden it and Brute-force attacks on WordPress: how they work and how to stop them.