Safe execution of system() or exec() using environment variables
I have two strings, both of which can be set by the user, eg
char *command = "vim $VAR"; char *myVar = "/tmp/something";
I want to use *
myVar to perform
I tried concatenating them as environment variables (e.g. (pseudocode)
system("VAR="+*myVar+"; "+ *command), but the user controls
myVar so it would be very insecure and wrong.
I considered marking spaces to replace
$var directly and passing the result to
exec(), but was worried that it would be too awkward to mark shell command arguments correctly.
think the solution is by doing something like exec(“sh”, “-c”, command, “–argument”, “
VAR", myVar), but I don’t see anything in the sh/dash/bash man page that allows environment variables to be set this way.
EDIT: I just saw execvpe(), which has a parameter to set the environment variable from the key=value string. Is it safe to enter with untrusted values?
How do I do this safely?
You can perform some string substitution on
the value of myVar—put it inside single quotes, and replace all single quote (character ‘) strings ‘
' with four characters. If you don’t make implementation mistakes, it’s cumbersome but safe. If possible, use a library that does it for you
If your program is single-threaded, I recommend a different solution that doesn’t involve tedious references. You talked about setting environment variables… Well, let’s do it: set
VAR as an environment variable.
setenv("VAR", myVar, 1); system(command); unsetenv("VAR")
omitted the error checking, and I’m assuming
VAR isn’t needed elsewhere in the program (this solution becomes more tedious if needed because you need to remember the old values).
If you want fine-grained control over the environment in which commands run, you can do so in
fork, execve (or
> above waitpid. This requires more effort, but you can get Spirit Active.
Note that with the exception of string substitution
for "vim $VAR” in the C program, the command needs to be vim “$VAR” and not
vim $VAR regardless of your solution.
This is because in shell syntax, $VAR only means “the value of the variable VAR” when it is inside double quotes—
$VAR means “take the value of VAR, split it into words
, and expand each word into a filename wildcard pattern