I'm currently developing a web service that takes user input and passes it to a bash script as an argument.

I know that without sanitizing this allows for remote command execution. So I want to know if alphanumeric strings with hyphens are safe to pass as arguments? An example of such an argument will be "51173bae-ef64-4664-8a4c-0cf75acc3783".

Any help is much appreciated.

  • Safe against what? You should of course make sure and quote your string and not inject it directly into the command. Whether or not such a situation is secure or not depends on what your bash script is doing with it... – Conor Mancone Nov 20 '19 at 13:22
  • The script uses the arguments as parameters to some gcloud CLI commands, so that shouldn't cause any security issues since they are wrapped properly. What I'm asking is; if not sanitized something like script.sh <user_input&&malicious_command> is possible. Is something similar possible with only alphanumeric characters and hyphens? – limeeattack Nov 20 '19 at 13:28

Tl,DR: Yes. But beware that you misunderstand what's going on and this may be a source of vulnerabilities.

An argument of a program can be an arbitrary byte string that doesn't contain a null byte. The limitation with null bytes comes from the operating system. Depending on your programming language and its standard library, a null byte may be rejected, or it may be passed to the operating system which will truncate the argument at the first null byte.

Bash has no limitations on the content of arguments or more generally on the content of string variables, other than null bytes, which won't reach it anyway. However, beware that when using a locale with a multibyte character encoding such as UTF-8, string operations may give unexpected results on operands that contain byte sequences that aren't valid in the chosen encoding. ASCII strings (containing only code points 1–127) are always safe. Strings containing arbitrary sequences of non-null bytes are safe as long as you set LC_ALL=C or LC_CTYPE=C before manipulating them.

In bash, remember to always use double quotes around variable expansions and command substitutions (i.e. "$foo", not $foo). When you pass an argument to a program that takes command line options following Unix conventions, pass -- before the first non-option argument. See Why does my shell script choke on whitespace or other special characters? and Security implications of forgetting to quote a variable in bash/POSIX shells.

There is absolutely no problem with passing the argument <user_input&&malicious_command> to a bash script. That's a perfectly ordinary string. There is, however, a problem if you interpolate this string into a shell script. Passing an argument to a program and interpolating a string into a script are completely different operations. If you call your program through a function that wraps around exec (perhaps combined with fork as in spawn), this passes a list of strings as argument to the program and no interpolation is done. On the other hand, functions like system and popen take a single string as argument and they call a shell on that string. If you build this string by combining the name of a program and the argument(s) that you pass to this program, you need to take be careful with the content of the arguments. This has nothing to do with the program that you're calling, bash string or otherwise: the problem is that the intermediate shell parses the string. It's about how you call the program, not about the program you call.

If you call exec("foo.bash", my_string), everything is fine as long as my_string is a character string that doesn't contain nulls. If you call system("foo.bash " + my_string) (where + is string concatenation), this only works to pass the value of my_string as an argument if it doesn't contain characters that have a special meaning to the intermediate shell created by system.

The following characters have a special meaning to Unix shells, at least in some circumstances: null bytes, tab, newline (LF), space, !"#$&'()*;<=>?[\]^`{|}~. In particular, strings containing only digits, letters and - are safe. A safe way to protect a character string that doesn't contain null bytes is to replace each single quote ' by the 4-character sequence '\'' and surround the result with single quotes '…'. Note that this applies to Unix systems (including Linux, macOS, etc.), not to Windows which has a completely different shell. Note that in this paragraph, “safe” solely refers to the shell; as mentioned above, strings beginning with - are problematic when you invoke typical programs that take options following a Unix convention.

Avoid using functions that spawn an intermediate shell if you can. To call an external program, prefer functions that take the path to the program and the list of arguments separately.

| improve this answer | |
  • Thank you for answering my question so thoroughly. I'm glad that you mention popen as that's what I'm using to execute the script. I'll try to see if there's any way to avoid spawning an intermediate shell. – limeeattack Nov 21 '19 at 8:29

Yes, it is safe form an error-free perspective.

As long as they are not special characters they should not influence anything.

Take a look at the special characters listed here.

If you do not use any of them in your string there should be no problem whatsoever.

| improve this answer | |
  • Great! Thank you for the clarification! – limeeattack Nov 20 '19 at 13:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.