Can anyone point to some code that deals with the security of files access via a path specified (in part) by an environment variable, specifically for Unix and its variants, but Windows solutions are also of interest?
This is a big long question - I'm not sure how well it fits the SO paradigm.
Consider this scenario:
Background:
Current checking:
Assume that the 'as installed' value of $PQRHOME is /opt/pqr.
Known attack:
Given that PQR currently behaves as described, and is a large package (multiple millions of lines of code, developed over more than a decade to a variety of coding standards, which were frequently ignored, anyway), what techniques would you use to remediate the problem?
Known options include:
Proposed criteria for secure paths:
The POSIX function realpath() provides a mapping service that will map /home/attacker/pqr to /opt/pqr; it does not do the security checking, but that need only be done on the resolved path.
So, with all that as background, is there any known software which goes through vaguely related gyrations to ensure its security? Is this being overly paranoid? (If so, why - and are you really sure?)
Edited:
Thanks for the various comments.
@S.Lott: The attack (outlined in the question) means that at least one setuid root program can be made to use a format string of the (unprivileged) user's choosing, and can at least crash the program and therefore most probably can acquire a root shell. It requires local shell access, fortunately; it is not a remote attack. It requires a non-negligible amount of knowledge to get there, but I consider it unwise to assume that the expertise is not 'out there'.
So, what I'm describing is a 'format string vulnerability' and the known attack path involves faking the program out so that although it thinks it is accessing secure message files, it actually goes and uses the message files (which contain format strings) that are under the control of the user, not under the control of the software.
Option 2 works, if you write a new value for $PQRHOME after resolving its real path and check its security. That way very little of your code needs changing thereafter.
As far as keeping the setuid privileges, it would help if you can do some sort of privilege separation, so that any operations involving input from the real user runs under the real uid. The privileged process and the real-uid process then talk using a socketpair or something like it.
Well, it sounds paranoid, but if it is or not depends on which system(s) your application is running on and which damage can an attacker do.
So, if your userbase is possibly hostile and if the damage is possibly very high, I'd go for the option 4, but modified as follows to remove its drawbacks.
Let me quote two relevant things:
1)
The programs currently check that $PQRHOME and key directories under it are 'safe' (owned by pqrusr, belong to pqrgrp, do not have public write access).
2)
Thereafter, programs access files under $PQRHOME via the full value of environment variable.
You don't need to actually hard-code the full path, you can hard-code just the relative path from the "program" you mentioned in 1) to the path mentioned in 2) where the files are.
Issue to control:
a) you must be sure that there isn't anything "attacker-accessible" (e.g. in term of symlinks) in between the executable's path and the files' path
b) you must be sure that the executable check its own path in a reliable way, but this should not be a problem in all the Unix'es I know (but I don't know all 'em and I don't know windows at all).
EDITED after the 3rd comment:
If your OS support /proc, the syslink /proc/${pid}/exe is the best way to solve b)
EDITED after sleeping on it:
Is the installation a "safe" process? If so, you might create (at installation time) a wrapper script. This script should be executable but not writable (and possibly neither readable). It would set the $PQRHOME env var to the "safe" value and then call your actual program (it might eventually do other useful things too). Since in UNIX the env vars of a running process cannot be changed by anything else but the running process, you are safe (of course the env vars can be changed by the parent before the process starts). I do not know if this approach works in Windows, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With