PSA: Creating world-unreadable files

Michał ‘mina86’ Nazarewicz | 5 lutego 2017

I’ve been reading tutorials on using key files for disk encryption. Common approach for creating such a file is:

Step 1: Create a random key file

head -c 4096 /dev/urandom >keyfile

Step 2: Make the file readable by owner only

chmod 400 keyfile

*sighs* Please, stop doing this and spreading that method. The correct way of achieving the effect is:

Step 1: Create a random key file readable by owner only

(umask 077; head -c 64 /dev/random >keyfile)

Or if the file needs to be created as root while command is run by a different user:

Step 1: Create a random key file readable by root only

sudo sh -c 'umask 077; head -c 64 /dev/random >keyfile'

The first method creates the file as world-readable¹ and before its permission are changed anyone can read it. The second method creates the file as readable only by its owner from the very beginning thus preventing the secret disclosure.

This attack is possible even if data is written after permissions are tightened. For example in situation such as:

exec 3>keyfile
chmod 400 keyfile
head -c 64 /dev/random >&3
exec 3>&-

Changing file permissions does not affect existing file descriptors so if attacker opens the file prior to the invocation of chmod command they can keep it open and wait for the data to trickle in.

This may sound like a theoretical exercise which has no barring on reality but the proper way of doing things is so trivial there’s no reason not to go with it. Indeed, it’s actually shorter.

¹ This does depend on various factors. For example whether the directory the file is created in has executable bit set. Some paranoid security-conscious users may already have umask set to 077 but beware that sudo resets it to the default 022.