After an incident, advice often says to set folders to 755 and files to 644. Those values can be reasonable on some hosts, but ownership, PHP handler, shared groups, ACLs and deployment method decide whether they are safe.
Permissions are defence in depth. They do not remove stolen credentials or vulnerable code.
Map the hosting execution model
Ask who owns files and which user PHP-FPM/Apache runs as. Compare known-good files created by WordPress, SFTP and deployment tools.
On shared hosting, each account may run PHP as its own user. On older/shared group models, more restrictive changes can break uploads/updates.
Do not run recursive chmod from an unclear working directory.
Preserve current metadata
Take a snapshot and export path, owner, group, mode and ACL information before changes. Unexpected ownership can reveal cross-site writes or root-level modification.
Record symlinks and mounted/shared storage. Avoid following symlinks into another application.
Keep evidence with usernames redacted in external reports.
Separate code from writable content
WordPress needs writes for uploads, caches, updates and sometimes language/generated assets. Document each expected writable directory and its owning component.
PHP execution should normally be blocked in uploads through server-supported configuration. Making uploads non-writable prevents media but does not clean malicious PHP already present.
Avoid world-writable (777) permissions as a troubleshooting shortcut.
Restore ownership first
Use the hosting panel/provider or authorised system administrator to set the correct user/group. Changing modes cannot fix a file owned by the wrong account.
Do not chown across a shared server without exact path/authority. On managed hosting, manual ownership changes may conflict with platform controls.
Verify deployment and WordPress update users can work without sharing a broad account.
Apply least privilege by area
Use the host’s documented baseline, then tighten sensitive configuration such as wp-config.php where compatible. Keep plugin/theme code writable only by the intended update/deployment process.
Disabling dashboard file editing can reduce one path:
define('DISALLOW_FILE_EDIT', true);
It does not prevent a compromised plugin or SFTP account from writing. Test the editorial/update workflow after adding it.
Protect configuration and environment files
Inventory .env, .user.ini, php.ini, web-server includes and deployment configuration near the WordPress root. They may contain secrets or PHP prepend directives and can be more sensitive than ordinary plugin files.
Ensure they are not publicly downloadable and are readable only by the necessary service/deployment users. Do not relocate a configuration file without checking how hosting tools, backups and cron reference it.
Rotate secrets that the incident could expose, then verify the old values are not retained in public archives or repository history.
Review ACLs and parent directories
POSIX modes may look restrictive while ACLs grant another user access. Parent directory permissions also control traversal and file creation.
Inspect addon-domain nesting and sibling-site ownership. Separate critical sites into distinct hosting users when practical.
Remove abandoned FTP/deployment users and rotate compromised credentials.
Test updates and rollback
In staging, upload media, update a safe plugin, regenerate caches and run backups. Watch which paths require writes and document exceptions.
Do not grant a whole document root write access because one cache directory fails. Correct that component’s specific path/owner.
Monitor permission changes after automated deployments.
Verify security outcome
Confirm no executable files remain in uploads, trusted code hashes are clean and known users alone can modify them. Observe beyond the former reinfection period.
Request help when ownership is mixed, ACLs are unclear or updates require unsafe modes. Send a redacted path/ownership map, not server credentials.
The correct result is maintainable least privilege with a known writer—not a blanket number applied to every file.