-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use of eval
introduces possibility of shell injection unnecessarily.
#50
Comments
- Avoid calling jq more than once per operation. To do this, we have `jq` generate assignments with eval-safe escaping setting shell variables. - Avoid passing anything but options through eval (keeping options themselves from being eval'd will be a compatibility-breaking change, and is the subject of cloud-gov#50). - Avoid using `echo` to handle non-constant data (which introduces substantial portability problems across different implementations of `sh`; see https://unix.stackexchange.com/a/65819/3113 and https://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html). - Handle "null" return value from `aws s3api list-objects` gratefully (cloud-gov#49)
- Avoid calling jq more than once per operation. To do this, we have `jq` generate assignments with eval-safe escaping setting shell variables. - Avoid passing anything but options through eval (keeping options themselves from being eval'd will be a compatibility-breaking change, and is the subject of cloud-gov#50). - Avoid using `echo` to handle non-constant data (which introduces substantial portability problems across different implementations of `sh`; see https://unix.stackexchange.com/a/65819/3113 and https://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html). - Handle "null" return value from `aws s3api list-objects` gratefully (cloud-gov#49)
Thinking about it a bit more: There is a reasonable opportunity to avoid the shell injection vulnerability without breaking backwards compatibility if we're willing to change the shell from In bash I've described this in more detail at https://stackoverflow.com/questions/26067249/reading-quoted-escaped-arguments-correctly-from-a-string |
Hi Charles, Thanks for these PRs and suggestions. Things are kind of quiet there this week, so we'll dig into them more next week. Are you using Happy New Year! --Peter |
Thank you! Next week is actually sooner than I'd expected; my spouse used to work for FHWA and was advising me not to expect anyone back in the office for a good while. Yes, I am actually using this (particularly, a local build with #51 applied) in practice. (Might end up moving away from it at some point, or at least supplementing it with an additional resource, as |
BTW, if y'all are comfortable in practice with adding bash as a dependency, I'll be glad to put together a PR after #51 is dealt with (to avoid any need to deal with merge conflicts from having two changesets touching the same pieces in flight). I might be tempted to start using xargs to get shell-like parsing following the preexisting/documented behavior for |
Unfortunately, fixing this will require changing the configuration format -- it may need to wait for a new major release.
Current configuration is of the form:
...that is to say, correct shell escaping is required to be part of the data and the boundary between individual options is not meaningful (for example,
--exclude
is one argument and*
is another, but they're entered as part of the same list element; one could add- "--exclude '*' --include 'results/*'"
as a single element with the exact same semantic meaning).The use of
eval
makes this possible, but that also introduces potential for human error (any command substitution, redirection, globbing, or other syntax present in the options array will be evaluated by the shell executing the scripts).A safe alternative would be to instead use configuration of the form:
...and have
jq
be responsible for transforming it into a shell array, as follows:...which runs the command:
...allowing
"$@"
to be expanded to the desired arguments later in the script.Notes
printf
overecho
, see https://unix.stackexchange.com/a/65819/3113, or the APPLICATION USAGE and RATIONALE sections of the POSIX standard forecho
)eval
a single string is strongly preferred over passing it a list of strings. Notably, passingeval
multiple strings does not meaningfully pass it distinct arguments: the strings it is passed are concatenated together (with spaces between them) into a single larger string before that single, larger string is passed to the parser. I'm glad to provide some examples of cases where this results in unintended behavior should those be desired.The text was updated successfully, but these errors were encountered: