Using umask
to prevent world-readable password
sniffing
Abstract
A brief note advocating the use of umask
as best
practice for dealing with password files on multi-user machines
The background: on a *nix system, traditionally all files are world-readable. This is good, and often useful. Putting passwords in clear-text files though is a perennial mistake and is often a problem at Cambridge for the SRCF. Commonly, users work around this by installing an application (say MediaWiki), then quickly changing the permissions on the configuration files generated where the database passwords are stored. Most years some malicious student or other runs a password-sniffing script and gets some passwords, but the probability of a nasty script running on any particular day is low, and it is very unlikely that a script running through files sequentially will spot anything in the short window the password is readable.
Unfortunately, this does procedure does not follow good practices and
I suggest is easily enough exploitable to cause some concern. Scripts
searching all files must necessarily take a lot of disk and
CPU time, a much smaller, less likely to be detected
script would lie largely dormant, grabbing a list of recently changed files
each second from some inotify
-like interface. Most files would
be entirely ignored, and just a few likely-looking filenames (such as
LocalSettings.php
) would be picked up on.
The defense is actually rather easy, and explains the standard best
practices approach to password files. Instead of making the file, then
changing its permissions to not readable, leading to the vulnerability
above, use umask
to ensure the file is never readable in the
first place.
For MediaWiki, this takes a little faff, for example. We need the
first-run install page to load to generate the initial config, but it checks
for the precence of LocalSettings.php
to run that. So,
that explains the procedure on the SRCF
FAQ page which tells you to run the MediaWiki install
process until the password form appears, then, before submitting it and
generating the password file running these:
$
mkdir ~/<socname>/public_html/wiki/config$
umask 0007$
touch ~/<socname>/public_html/wiki/config/LocalSettings.php$
chgrp <socname> ~/<socname>/public_html/wiki/config/LocalSettings.php$
umask 0002
Then, submitting the form overwrites the blank password file, but leaves it with the same permissions.
Note
If you refuse to believe me that a script can read a non-readable file, run this simple example:
$
touch test$
cat > test.py <<EOF>
import time;>
handle = open ('test.txt');>
while (True):>
time.sleep(2);>
handle.seek(0);>
print handle.read();>
EOF$
python test.py
Then in another terminal,
$
chmod ugo-r test
still leaves the first one reading the file, because permissions are only checked when handing out file handles, not each time they are used.