Incorrect file permissions are a common, often invisible security weakness — either too permissive (exposing sensitive files) or too restrictive (breaking application functionality). This guide covers auditing and correcting them systematically.
Quick Refresher: Reading Permission Notation
-rwxr-xr-- 1 www-data www-data 1024 Jan 1 12:00 app.conf
Three groups of three: owner (rwx), group (r-x), others (r--). r=read, w=write, x=execute.
Step 1 — Find World-Writable Files (High Risk)
find / -xdev -type f -perm -0002 -ls 2>/dev/null
World-writable files can be modified by any user on the system — a serious risk if the server is ever compromised via a low-privilege account.
Step 2 — Find Files with No Owner
find / -xdev -nouser -o -nogroup 2>/dev/null
Orphaned ownership (often from a deleted user account) can indicate leftover artifacts worth investigating and cleaning up.
Step 3 — Check for Overly Permissive SSH/Sensitive File Permissions
ls -la ~/.ssh/
stat -c "%a %n" ~/.ssh/id_rsa /etc/shadow /etc/ssh/sshd_config
Private keys should be 600 (owner read/write only); /etc/shadow should never be world-readable.
Step 4 — Audit Web Server Document Root Permissions
find /var/www -type f -perm -0002
Web-accessible files being world-writable is a common path to compromise — if an attacker gains any foothold, writable files under the document root let them modify served content directly.
Step 5 — Set Correct Ownership for Web Applications
sudo chown -R www-data:www-data /var/www/myapp
sudo find /var/www/myapp -type d -exec chmod 755 {} \;
sudo find /var/www/myapp -type f -exec chmod 644 {} \;
A standard, safe baseline: directories 755 (owner full access, others read/execute for traversal), files 644 (owner read/write, others read-only) — adjusted upward only for specific files/directories that genuinely need write access (like an uploads folder).
Step 6 — Restrict Sensitive Configuration Files Further
chmod 600 /var/www/myapp/.env
Files containing secrets (environment files, database credentials) should be readable only by the application's own user, not group or world-readable.
Step 7 — Check for Unnecessary SUID/SGID Binaries
find / -xdev -perm -4000 -o -perm -2000 2>/dev/null
SUID/SGID binaries run with elevated privileges regardless of who executes them — a legitimate but sensitive mechanism. Review the list for anything unexpected or unnecessary that could represent a privilege escalation path.
Automating Regular Permission Audits
sudo nano /usr/local/bin/permission-audit.sh
#!/bin/bash
echo "=== World-writable files ==="
find / -xdev -type f -perm -0002 2>/dev/null
echo "=== Files with no owner ==="
find / -xdev -nouser -o -nogroup 2>/dev/null
sudo crontab -e
0 4 * * 0 /usr/local/bin/permission-audit.sh | mail -s "Weekly Permission Audit" [email protected]
Using a Dedicated Auditing Tool (More Thorough)
For a more comprehensive check, tools like Lynis (see the security auditing tools referenced in Advanced Security & Compliance) include permission checks as part of a broader system security scan.
Common Errors
Application breaks after tightening permissions — some applications genuinely need write access to specific directories (uploads, cache, logs); identify exactly which paths need it rather than reverting to broad permissive settings everywhere.
"Permission denied" errors after changing ownership — verify you changed ownership to the correct user (the one the actual service/process runs as, e.g. www-data for Nginx/Apache, not your personal sudo user).
Best Practices
- Follow the principle of least privilege — grant only the access a file/process genuinely needs
- Never leave sensitive files (keys, credentials,
.env) world-readable - Audit permissions periodically, not just once at initial setup
Continue Reading
- VPS Security Checklist for Beginners
- How to Implement the Principle of Least Privilege on a Linux VPS
- How to Harden a Fresh Linux VPS in 15 Minutes
Browse more articles in Server Security & Hardening.