Skip to main content

Chapter 9.1 - Securing Permissions

Learning Objectives​

By the end of this chapter, you will be able to:

  • Apply the principle of least privilege
  • Secure file permissions
  • Understand the risks of broad permissions
  • Audit system permissions
  • Correct incorrect permissions

Principle of Least Privilege​

Concept​

Give only the necessary permissions, nothing more.

Advantages:

  • Reduced attack surface
  • Limitation of damage
  • Security compliance

Secured Permissions​

Normal Files​

# Configuration files
chmod 644 fichier.conf # rw-r--r--
chmod 600 fichier.conf # rw------- (private)

# Executable scripts
chmod 755 script.sh # rwxr-xr-x
chmod 700 script.sh # rwx------ (private)

# Sensitive files
chmod 600 .ssh/id_rsa # Private key
chmod 644 .ssh/id_rsa.pub # Public key
chmod 700 .ssh/ # SSH directory

Directories​

# Normal directories
chmod 755 repertoire/ # rwxr-xr-x

# Private directories
chmod 700 repertoire/ # rwx------

# Shared directories
chmod 775 shared/ # rwxrwxr-x
chmod 1777 /tmp # Sticky bit

Dangerous Permissions​

To Avoid​

# 777 - All rights (DANGEROUS!)
chmod 777 fichier # AVOID!

# Unnecessary SUID/SGID
chmod u+s script.sh # Check necessity

# World-writable directories
chmod 777 repertoire/ # AVOID!

Detect​

# Files with broad permissions
find /home -type f -perm -o+w
find / -type f -perm 777 2>/dev/null

# World-writable directories
find / -type d -perm -o+w ! -path "/proc/*" 2>/dev/null

# SUID/SGID files
find / -type f -perm /4000 2>/dev/null # SUID
find / -type f -perm /2000 2>/dev/null # SGID

SSH Security​

Correct Permissions​

# .ssh directory
chmod 700 ~/.ssh

# Private keys
chmod 600 ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_ed25519

# Public keys
chmod 644 ~/.ssh/id_rsa.pub
chmod 644 ~/.ssh/authorized_keys

# Config
chmod 600 ~/.ssh/config

Verification​

# Verification script
#!/bin/bash
SSH_DIR="$HOME/.ssh"

if [ -d "$SSH_DIR" ]; then
# Check directory permissions
PERMS=$(stat -c "%a" "$SSH_DIR")
if [ "$PERMS" != "700" ]; then
echo "WARNING: .ssh should be 700, currently $PERMS"
fi

# Check private keys
for key in "$SSH_DIR"/id_*; do
if [ -f "$key" ] && [[ "$key" != *.pub ]]; then
PERMS=$(stat -c "%a" "$key")
if [ "$PERMS" != "600" ]; then
echo "WARNING: $key should be 600, currently $PERMS"
fi
fi
done
fi

Cron Security​

Crontab Permissions​

# User crontab
chmod 600 ~/.crontab # If external file

# Check system crontab
ls -l /etc/crontab
ls -l /etc/cron.d/*

Cron Environment​

# Secure crontab
PATH=/usr/bin:/bin
SHELL=/bin/bash
MAILTO=admin@example.com

# Use absolute paths
0 2 * * * /usr/local/bin/backup.sh

# Redirect output
0 2 * * * /usr/local/bin/script.sh > /var/log/script.log 2>&1

# Do not use undefined variables

Secure Cron Scripts​

#!/bin/bash
# Secure cron script

# Security options
set -euo pipefail

# Absolute paths
SCRIPT_DIR="/usr/local/bin"
LOG_FILE="/var/log/my-script.log"

# Logging function
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"
}

# Checks
if [ ! -f "$SCRIPT_DIR/config" ]; then
log "ERROR: Missing config file"
exit 1
fi

# Processing...
log "Start processing"
# ...
log "End processing"

Permissions Audit​

Audit Script​

#!/bin/bash
# Permissions audit

echo "=== World-writable files ==="
find /home -type f -perm -o+w 2>/dev/null

echo "=== World-writable directories ==="
find /home -type d -perm -o+w 2>/dev/null

echo "=== SUID files ==="
find /home -type f -perm /4000 2>/dev/null

echo "=== SGID files ==="
find /home -type f -perm /2000 2>/dev/null

echo "=== SSH Permissions ==="
if [ -d ~/.ssh ]; then
ls -la ~/.ssh
fi

Automatic Correction​

#!/bin/bash
# Correct SSH permissions

SSH_DIR="$HOME/.ssh"

if [ -d "$SSH_DIR" ]; then
chmod 700 "$SSH_DIR"

# Private keys
find "$SSH_DIR" -name "id_*" ! -name "*.pub" -exec chmod 600 {} \;

# Public keys
find "$SSH_DIR" -name "*.pub" -exec chmod 644 {} \;

# authorized_keys
[ -f "$SSH_DIR/authorized_keys" ] && chmod 600 "$SSH_DIR/authorized_keys"

# config
[ -f "$SSH_DIR/config" ] && chmod 600 "$SSH_DIR/config"

echo "SSH permissions corrected"
fi

Best Practices​

Files​

  • 644 for normal files
  • 600 for sensitive files
  • 755 for executable scripts
  • 700 for private scripts

Directories​

  • 755 for normal directories
  • 700 for private directories
  • 775 for shared directories (with group)
  • 1777 for /tmp (sticky bit)

Checks​

  • Regularly audit
  • Automate with scripts
  • Document exceptions
  • Review after changes

Summary​

In this chapter, you learned:

Least privilege: Minimal necessary permissions
Securing: Appropriate permissions by type
Detection: Find dangerous permissions
SSH: Correct permissions for keys and config
Cron: Secure scripts and environment
Audit: Scripts to check and correct


Next Steps​

Chapter 9.2: Sudo configuration
Chapter 9.3: Firewall


Chapter created on: December 2024