[ 
https://issues.apache.org/jira/browse/JCLOUDS-623?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Werner Buck updated JCLOUDS-623:
--------------------------------

    Description: 
In the file SudoAwareInitManager sudo is used to grant superuser access to 
execute the initscript.

This can be observed at line 116 of 
https://github.com/jclouds/jclouds/blob/4c74b497547e42b8bdc94dbae3d4cd94ff3945d6/compute/src/main/java/org/jclouds/compute/callables/SudoAwareInitManager.java

command = String.format("echo '%s'|sudo -S %s %s", 
node.getCredentials().getPassword(),

The problem is that submitting providing the password as cleartext means it can 
be intercepted for example in 'ps' by another user.

In another file the password is not echo'd and piped in but redirected:  
https://github.com/jclouds/jclouds/blob/4c74b497547e42b8bdc94dbae3d4cd94ff3945d6/compute/src/main/java/org/jclouds/compute/callables/RunScriptOnNodeUsingSsh.java

I am unsure if this is more secure, but the command as a whole gets transmitted 
to the remote shell I believe.

I propose using execChannel instead of 'exec' of SshClient for all commands and 
use InputStream/Outputstreams to 'catch' sudo asking for a password and only if 
asked print it. 
This also allows for better error control as we can catch if sudo was succesful 
or not far earlier in the script execution process.

Instead of just "sudo -S command" I propose the following more elaborate 
command:

randomint=1231443
prompt = "[sudo] jclouds-$randomint requires a password: "
successkey = SUCCESS-$randomint

sudo -k && sudo -H -S -p "$prompt" -u root /bin/sh -c "echo $successkey && 
/command/to/execute"

This deserves some explaining.  sudo -k kills any active sudo session. The -p 
means that the prompt provided will be shown to the user. This allows us to 
always be able to catch this output and with $randomint inserted we are sure 
that it is a password prompt.

In stderr we catch prompt and then pass the password to the stdin. Then we 
listen to stdout to catch "SUCCESS-$randomint" with $randomint being the same 
as the prompt.  If any other output other than that succeskey shows up we know 
it is not succesful.

This insight into using sudo this way comes from the way that Ansible is 
implemented.


  was:
In the file SudoAwareInitManager sudo is used to grant superuser access to 
execute the initscript.

This can be observed at line 116 of 
https://github.com/jclouds/jclouds/blob/4c74b497547e42b8bdc94dbae3d4cd94ff3945d6/compute/src/main/java/org/jclouds/compute/callables/SudoAwareInitManager.java

command = String.format("echo '%s'|sudo -S %s %s", 
node.getCredentials().getPassword(),

The problem is that submitting providing the password as cleartext means it can 
be intercepted for example in 'ps' by another user.

In another file the password is not echo'd and piped in but redirected:  
https://github.com/jclouds/jclouds/blob/4c74b497547e42b8bdc94dbae3d4cd94ff3945d6/compute/src/main/java/org/jclouds/compute/callables/RunScriptOnNodeUsingSsh.java

I am unsure if this is more secure, but the command as a whole gets transmitted 
to the remote shell I believe.

I propose using execChannel instead of 'exec' of SshClient for all commands and 
use InputStream/Outputstreams to 'catch' sudo asking for a password and only if 
asked print it. 
This also allows for better error control as we can catch if sudo was succesful 
or not far earlier in the script execution process.

Instead of just "sudo -S command" I propose the following more elaborate 
command:

randomint=$randomint
prompt = "[sudo] jclouds-$randomint requires a password: "
successkey = SUCCESS-$randomint

sudo -k && sudo -H -S -p "$prompt" -u root /bin/sh -c "echo $successkey && 
/command/to/execute"

This deserves some explaining.  sudo -k kills any active sudo session. The -p 
means that the prompt provided will be shown to the user. This allows us to 
always be able to catch this output and with $randomint inserted we are sure 
that it is a password prompt.

In stderr we catch prompt and then pass the password to the stdin. Then we 
listen to stdout to catch "SUCCESS-$randomint" with $randomint being the same 
as the prompt.  If any other output other than that succeskey shows up we know 
it is not succesful.

This insight into using sudo this way comes from the way that Ansible is 
implemented.



> Insecure passing of password to sudo on SubmitScriptOnNode with initscript.
> ---------------------------------------------------------------------------
>
>                 Key: JCLOUDS-623
>                 URL: https://issues.apache.org/jira/browse/JCLOUDS-623
>             Project: jclouds
>          Issue Type: Bug
>          Components: jclouds-compute
>    Affects Versions: 1.8.0
>            Reporter: Werner Buck
>              Labels: run, security, ssh, sudo
>
> In the file SudoAwareInitManager sudo is used to grant superuser access to 
> execute the initscript.
> This can be observed at line 116 of 
> https://github.com/jclouds/jclouds/blob/4c74b497547e42b8bdc94dbae3d4cd94ff3945d6/compute/src/main/java/org/jclouds/compute/callables/SudoAwareInitManager.java
> command = String.format("echo '%s'|sudo -S %s %s", 
> node.getCredentials().getPassword(),
> The problem is that submitting providing the password as cleartext means it 
> can be intercepted for example in 'ps' by another user.
> In another file the password is not echo'd and piped in but redirected:  
> https://github.com/jclouds/jclouds/blob/4c74b497547e42b8bdc94dbae3d4cd94ff3945d6/compute/src/main/java/org/jclouds/compute/callables/RunScriptOnNodeUsingSsh.java
> I am unsure if this is more secure, but the command as a whole gets 
> transmitted to the remote shell I believe.
> I propose using execChannel instead of 'exec' of SshClient for all commands 
> and use InputStream/Outputstreams to 'catch' sudo asking for a password and 
> only if asked print it. 
> This also allows for better error control as we can catch if sudo was 
> succesful or not far earlier in the script execution process.
> Instead of just "sudo -S command" I propose the following more elaborate 
> command:
> randomint=1231443
> prompt = "[sudo] jclouds-$randomint requires a password: "
> successkey = SUCCESS-$randomint
> sudo -k && sudo -H -S -p "$prompt" -u root /bin/sh -c "echo $successkey && 
> /command/to/execute"
> This deserves some explaining.  sudo -k kills any active sudo session. The -p 
> means that the prompt provided will be shown to the user. This allows us to 
> always be able to catch this output and with $randomint inserted we are sure 
> that it is a password prompt.
> In stderr we catch prompt and then pass the password to the stdin. Then we 
> listen to stdout to catch "SUCCESS-$randomint" with $randomint being the same 
> as the prompt.  If any other output other than that succeskey shows up we 
> know it is not succesful.
> This insight into using sudo this way comes from the way that Ansible is 
> implemented.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to