Security Implications of PermitUserEnvironment in SSH: Risks, Exploits, and Secure Alternatives for DB Credentials


2 views

When PermitUserEnvironment is enabled in sshd_config, it creates a vector for privilege escalation and configuration bypass through environment variable manipulation. The official OpenSSH documentation explicitly warns about LD_PRELOAD attacks, but the risks extend further:

# Example vulnerable configuration (DON'T USE):
PermitUserEnvironment yes
AcceptEnv LANG LC_*

Attackers can leverage this setting in multiple ways:

  • Library Injection: Setting LD_PRELOAD=/malicious_lib.so to intercept system calls
  • Path Hijacking: Modifying PATH to point to attacker-controlled binaries
  • Credential Exposure: Environment variables appear in process listings (ps -eww)
# Example attack using .ssh/environment:
echo "LD_PRELOAD=/tmp/evil.so" > ~/.ssh/environment
chmod 600 ~/.ssh/environment

Instead of environment variables, consider these approaches:

1. SSH Config with LocalCommand

# ~/.ssh/config
Host db-host
  HostName db.example.com
  User dbuser
  LocalCommand export DB_PASS=$(security find-generic-password -s "db_creds" -w)

2. Encrypted Credential Files

# Secure credential storage example
openssl enc -aes-256-cbc -pbkdf2 -in db_creds.txt -out db_creds.enc
# Decrypt during connection:
ssh db-host "export \$(openssl enc -d -aes-256-cbc -pbkdf2 -in db_creds.enc | xargs)"

If you must use PermitUserEnvironment, implement these restrictions:

# /etc/ssh/sshd_config
PermitUserEnvironment no
Match User dbuser
  PermitUserEnvironment yes
  AcceptEnv DB_HOST DB_USER  # Explicitly allow only specific vars

Combine with filesystem protections:

chattr +i ~dbuser/.ssh/environment
restorecon -Rv ~dbuser/.ssh

Implement these detection measures:

# Audit rule for environment file modifications
-a always,exit -F path=/home/*/.ssh/environment -F perm=wa -k ssh_user_env

When PermitUserEnvironment is enabled in sshd_config, users can define environment variables through ~/.ssh/environment or authorized_keys environment options. This creates several attack vectors:

# Example of dangerous environment variables:
LD_PRELOAD=/path/to/malicious_library.so
LD_LIBRARY_PATH=/tmp/compromised
PATH=/home/attacker/bin:$PATH

Attackers can leverage environment variables to:

  • Preload malicious libraries via LD_PRELOAD
  • Hijack binary execution paths through PATH manipulation
  • Bypass security controls using LD_DEBUG or similar debug variables

While storing DB credentials in environment variables might seem convenient, consider these alternatives:

# Secure alternative using ssh forced commands
command="export DB_PASS=correct-horse-battery-staple; $SSH_ORIGINAL_COMMAND" ssh-rsa AAA... key-comment

# Better approach using configuration management:
# Store secrets in tools like HashiCorp Vault or AWS Secrets Manager

If you must use environment variables:

# In sshd_config:
PermitUserEnvironment no
Match User dbuser
    PermitUserEnvironment yes
    AcceptEnv DB_HOST DB_USER

# In authorized_keys:
environment="DB_PASS=encrypted-value" ssh-rsa AAA...

Implement these security controls:

  • Regularly audit ~/.ssh/environment files
  • Monitor for unusual environment variables in process listings
  • Use SELinux/AppArmor to restrict library loading