Rundeck option input, shell quoting, and security issues

2,262 views
Skip to first unread message

Greg Schueler

unread,
Apr 11, 2013, 1:17:28 PM4/11/13
to rundeck...@googlegroups.com
Hi all,

I wanted to bring up an issue (https://github.com/dtolabs/rundeck/issues/298) that points out the potential for unintended and risky behavior when a job option value is substituted in a shell command.  The risk is that if the Job option allows unrestricted user input, the shell command run in your job might inadvertently allow the user to execute arbitrary commands if they pass in shell-special characters.  (Thanks to Charles Duffy for raising this issue.)

For this reason I'd recommend that you *always* set your Job Options to have some kind of restriction on the allowed values they accept: you can either put in a hardcoded list of allowed strings, or use the regex to restrict the allowed characters.

Also, the user input can be passed directly to the command without first being interpreted by the shell by using the $RD_OPTION_NAME environment variable instead of ${option.name}.  In that case, the shell will substitute the value with appropriate escaping. (Note: for remote nodes, this requires modifying your sshd configuration.)

To re-iterate, you should be very careful in using ${property} expansion in your command string, and should either use the $RD_PROPERTY environment variable instead, or make sure your Option definition restricts user input.

This brings up the question of how the Command string you enter for a step is used, which has not been documented very well, and which I want to examine so that it can be done in a better fashion.

Currently the "command string" you enter in the Job definition is split into an array of arguments ("tokens"), separated by whitespace and allowing single/double quoting (but without escaped quotes). When it is executed embedded ${option.name} references are replaced.  Any of the resulting tokens containing quotes or whitespace are wrapped in more quotes.  Unfortunately this is only rudimentary quoting, and full escaping of shell-special characters is not performed.

For Local Node (server), the Command string is executed as:

    /bin/sh -c "<command string>"

For Remote Node (ssh), the command string is sent to the remote node via SSH, which uses whatever shell you have configured for the user account.

    (remote shell)$ <command string>

Ideally, any user-level input is sanitized so that no special characters seen by the Unix shell are left unescaped. What this means is that the mechanism for producing the final command string should be modified so that option values are correctly escaped.  However we still want to maintain the shell-like capabilities of the Command string in job definitions (such as file redirects, pipes, etc.).

So I'd like to propose this change:

* document and implement a more rigorous way to tokenize the command string
* when any tokens have embedded user input, they passed through quoting properly before executing
* when tokens do not embed user input, they are left as-is

Be aware, though, that even by escaping user input, it won't completely prevent you from using the user input in a risky way, such as passing it through a secondary level of shell intepretation where it would no longer be escaped:

    command string: /bin/bash -c "${option.input}"

execution:

    /bin/sh -c <command string>

In that case, the input will still be interpreted by the secondary shell.


Due to the nature of Rundeck (executing commands and scripts locally and on remote nodes), security is of course a serious concern, so just as a reminder let's go over some other security points for Rundeck:

1. Use Rundeck with HTTPS turned on.  See The Admin Guide for how to turn this feature on: http://rundeck.org/docs/administration/ssl.html
2. Change the default passwords if you use the file-based realm.properties, be sure to use hashed versions to store on disk: http://rundeck.org/docs/administration/authentication.html#realm.properties
3. Verify that your ACL Policy files don't grant more access than they should. http://rundeck.org/docs/administration/authorization.html
4. On remote nodes, you may want the Rundeck or role user account to be restricted in what specific shell commands they can run.
5. Verify Job Option input, using restrictions on the allowed values as mentioned above.
Reply all
Reply to author
Forward
0 new messages