A security-focused guide to chmod for sysadmins — covering permission models, SUID/SGID auditing, and fixing dangerous world-writable files in web server directories.

What is chmod?

The chmod command changes the access permissions of files and directories on Linux. It controls who — the owner, group, or all other users — can read, write, or execute a given file. On production servers, permission misconfigurations are one of the most exploitable classes of vulnerability: a world-writable file in a web root allows any process running under the web server account to overwrite application code, a SUID binary owned by root can escalate privileges if exploited, and incorrect directory permissions can expose sensitive configuration files to any local user. Understanding and auditing permissions with chmod is not optional — it is a baseline hardening requirement.

Syntax

chmod [options] mode file
chmod 755 /var/www/html/index.php
chmod -R 644 /etc/nginx/conf.d/
chmod u+x,go-wx script.sh
chmod a-s /usr/local/bin/suspicious_binary

Mode can be expressed in octal (e.g., 755) or symbolic notation (e.g., u+x). Octal is preferred in scripts for precision. The -R flag applies changes recursively to all files and subdirectories. Symbolic mode uses u (owner), g (group), o (others), a (all), combined with + (add), - (remove), = (set exact).

Key Options and Flags

Flag / ParameterDescriptionSecurity Note
-RApply permission change recursively to all files and subdirectoriesUse with caution — applying executable bits to all files in a directory including data files is a common mistake
-vVerbose mode — print each file as it is processed—
--reference=FILESet permissions identical to those of a reference file—
4000 (SUID)Set-User-ID bit — process runs with owner's privileges regardless of who executes itSUID on root-owned binaries is a privilege escalation vector — audit with find regularly
2000 (SGID)Set-Group-ID bit — process runs with group's privileges; on directories, new files inherit the groupSGID on directories can cause unintended group access to newly created files
1000 (Sticky)Sticky bit — on directories, only file owner can delete their own files (used on /tmp)Required on shared writable directories to prevent users from deleting each other's files

Common Use Cases

Find and Fix All 777 Permissions in a Web Root

World-writable files (777) in a web directory are a critical vulnerability. Any process running on the server — including a compromised web application — can overwrite them. The correct approach is to find all such files, reduce them to 644 for regular files and 755 for directories, then verify no legitimate process was relying on write access for others.

find /var/www/html -perm -0002 -type f -exec chmod o-w {} \;
find /var/www/html -perm -0002 -type d -exec chmod o-w {} \;

Audit and Remove SUID/SGID Bits from Unexpected Binaries

SUID binaries run with the file owner’s privileges — if owned by root, they execute as root regardless of who invokes them. An attacker with write access to a SUID binary, or the ability to exploit a vulnerability within one, can escalate to root. Regularly audit all SUID binaries outside expected system paths and remove the bit from anything that does not require it.

find / -perm /4000 -type f 2>/dev/null
find / -perm /6000 -type f 2>/dev/null
chmod a-s /path/to/unexpected_suid_binary

Set Secure Permissions on Configuration Files

Configuration files containing passwords, API keys, or connection strings should be readable only by their owning service account and root. A common pattern is 640 (owner read/write, group read, others nothing) for service config files, and 600 for private key files. Applying these consistently reduces exposure if one service account is compromised.

chmod 600 /etc/ssl/private/*.key
chmod 640 /etc/mysql/mysql.conf.d/mysqld.cnf
chmod 700 /root/.ssh

Security Relevance: Permissions as Attack Surface

File permissions are the Linux kernel’s primary access control mechanism. Misconfigured permissions are responsible for a significant proportion of privilege escalation paths on compromised systems. An attacker who gains access as the www-data user can escalate to a more privileged user if they find a world-writable file owned by that user, a SUID binary with a known exploit, or a config file readable by all that contains credentials. The real-world cost of a single world-writable file in a web root is not just defacement — it is full server compromise if the injected file is executed. Regular permission audits using find / -perm -0002 -type f and find / -perm /4000 should be part of every server’s baseline hardening checklist. Treat permission hardening as a first-day task when provisioning a server, not an afterthought.

  • Never set 777 permissions on files in web server directories — use 644 for files, 755 for directories
  • Any SUID binary outside /bin, /usr/bin, /usr/sbin that you did not deliberately install warrants immediate investigation
  • Applying chmod -R 755 to a directory containing private keys or config files with secrets will expose them to all local users
  • Config files with 644 permissions are readable by all users on the system — use 640 or 600 for files containing credentials
  • The sticky bit is NOT a security feature on files — only on directories (primarily /tmp)

Practical Examples

Recursively set correct web root permissions (files 644, directories 755)

find /var/www/html -type f -exec chmod 644 {} \;
find /var/www/html -type d -exec chmod 755 {} \;

This is the standard hardening pattern for a web root. Files are owner-read/write, world-readable only. Directories are traversable by all but writable only by owner. The web server process (www-data) reads but cannot write, preventing content injection via a compromised web app.

Audit all SUID root binaries on the system

find / -user root -perm -4000 -type f -ls 2>/dev/null | sort

This lists every file owned by root with the SUID bit set — the highest-risk class of binary on the system. Compare output against a known-good baseline. Any unexpected entry is a high-priority investigation item, as it represents a potential root escalation path.

Remove world-read from all private key files

find /etc/ssl /home /root -name '*.key' -o -name 'id_rsa' -o -name 'id_ed25519' 2>/dev/null | xargs chmod go-rwx

Private keys readable by other users or the web server process are a critical vulnerability. This command finds common private key files and strips all group and other permissions. Run after any deployment that touches key material.

Troubleshooting Common Issues

Problem: chmod -R changes permissions on symlinks pointing outside the directory

Solution: Use chmod -R --no-dereference or avoid applying chmod to symlinks directly. Better: use find -not -type l to exclude symlinks from the scope.

Problem: Changed permissions are not taking effect for the web server

Solution: Verify the effective user the web server runs as with ps aux | grep nginx or ps aux | grep apache. The file’s group ownership also matters — use chown www-data:www-data combined with chmod 640 rather than relying on world-readable bits.

Problem: SUID bit set but binary does not run as expected owner

Solution: The SUID bit is silently ignored on shell scripts by the Linux kernel as a security measure. It only functions on compiled ELF binaries. Also verify the filesystem is not mounted with the nosuid option using cat /proc/mounts | grep nosuid.

Summary

Correct file permissions are one of the most effective and underutilized defenses on Linux servers. The chmod command is the primary tool for enforcing the principle of least privilege at the filesystem level. Combine it with find for auditing at scale, apply it systematically during server provisioning, and revisit it after any deployment that modifies directory structures or installs new binaries.

  • Web root files should be 644 (files) and 755 (directories) — world-writable is never acceptable
  • Audit SUID binaries regularly with find / -user root -perm -4000 -type f 2>/dev/null — unexpected results require immediate investigation
  • Config files containing credentials should be 600 or 640, not 644 — world-readable config is a credential exposure risk

Is Your Server Configured with Least-Privilege Permissions?

INTRAM audits file system permissions as part of every managed Linux server deployment. We harden web roots, audit SUID binaries, and enforce consistent permission policies across your infrastructure.

Get a Security Audit

Let’s assess what your business actually needs.

We will use these details only to understand your request and reply appropriately.