How to securely manipulate user files

September 17, 2008

Here is a thesis:

The only way to securely do operations on user files is to do them as the user.

(You may also add 'correctly' to this.)

Over and over again I have seen root-run administrative programs and scripts try to manipulate user files in various ways, and over and over again I have seen them have problems and security holes. This is not because they were badly written, it's because there are a lot of race conditions lurking in the underbrush unless you are extraordinarily aware and careful.

The only genuinely reliable way out is to get rid of the entire problem. The problem is that an attacker is tricking you into manipulating the wrong files with special privileges, so get rid of the special privileges; when you manipulate files, do all of the manipulation as the user themselves. As a bonus you will get around any NFS root permission problems, where root actually has less privileges than the regular user does, not more.

(Please don't do this by temporarily switching the user's UID and then switching back, because that way you still have elevated privileges, even if they're latent.)

This is relatively easy in most shell scripts if you make yourself a basic runas command that just setuids (thoroughly) to the user and runs a command for you. The simple use of it is to just run every command that touches user files as the user by putting 'runas $USER' in front of the command. The more advanced usage is to split your shell script or program into multiple scripts, and then use runas in your main script to run the as-user script with appropriate arguments.

(You don't want to use su because it does too much; among other things, it runs a shell, often the user's shell, and users can have broken .bashrcs and .cshrcs. I've been there and stubbed my toe.)


Comments on this page:

By Dan.Astoorian at 2008-09-17 11:14:55:

(Please don't do this by temporarily switching the user's UID and then switching back, because that way you still have elevated privileges, even if they're latent.)

It really depends what you're doing with the files.

Suppose, for example, that you need a script to verify that all of your users have file permissions appropriate to your security policy--e.g., that they (or a piece of malware they've run) haven't done things like add inappropriate write permission to their home directory, or their .cshrc/.profile file, or .forward file.

The risk that the readdir() and stat() (and maybe chmod()) calls you're doing could be subverted to run the user's code and revert to the elevated privileges is tiny, and the cost of the pipe(), fork(), read()/write() calls needed to coordinate between the privileged dispatcher and the process operating on the user's files can be significant.

Worse, by scrubbing your privileges thoroughly, you may give the user the ability to ptrace() your process (e.g., by attaching to it with gdb) and affect its execution, so your dispatcher can no longer trust the reporting of the process operating on the user's files. This may amount to a greater threat than the latent elevated privileges you were trying to avoid.

--Dan

Written on 17 September 2008.
« A Unix without a test program
My experiences so far with Linux iSCSI target software »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Sep 17 01:39:30 2008
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.