If I understand correctly,
var is a variable in your programming language.
And in your programming language, you're asking a shell to interpret a string that is the concatenation of
"cd ", the content of that variable and
"; echo > create_a_file_here".
If then, yes, if the content of
var is not tightly controlled, it's a command injection vulnerability.
You could try and properly quote the content of the variable¹ in the syntax of the shell so it is guaranteed to be passed as a single argument to the
Another approach would be to pass the content of that variable another way. An obvious way would be to pass that in an environment variable. For instance, in C:
char *var = "; rm -rf /";
setenv("DIR", var, 1);
system("CDPATH= cd -P -- \"$DIR\" && echo something > create_a_file_here");
This time, the code that you ask the shell to interpret is fixed, we still need to write it properly in the shell's syntax (here assumed to be a POSIX-compliant shell):
- shell variable expansion must be quoted to prevent split+glob
- you need
cd to do a simple
- you need
-- to mark the end of options to avoid problems with
var starting with
+ in some shells)
- We set
CDPATH to the empty string in case it was is in the environment
- We only run the
echo command if
cd was successful.
There is (at least) one remaining problems: if
-, it doesn't chdir into the directory called
- but to the previous directory (as stored in
OLDPWD=- CDPATH= cd -P -- "$DIR" is not guaranteed to work around it. So you'd need something like:
"case $DIR in\n"
" (-) CDPATH= cd -P ./-;;\n"
" (*) CDPATH= cd -P -- \"$DIR\";;\n"
"esac && ....");
¹ Note that just doing a
is not the way to go, you'd be just moving the problem.
system(concat("cd \"", var, "\"; echo..."));
For instance, a
var = "$(rm -rf /)" would still be a problem.
The only reliable way to quote text for Bourne-like shells is to use single quotes and also take care of the single quotes that may occur in the string. For instance, turn a
char *var = "ab'cd" to
char *escaped_var = "'ab'\\''cd'". That is, replace all
'\'' and wrap the whole thing inside
That still assumes that that quoted string is not used within backticks, and you'd still need the