Skip to content
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

AMBARI-25942: Useshell=False wherever subprocess module with shell=True is used #3729

Open
wants to merge 1 commit into
base: branch-2.7
Choose a base branch
from

Conversation

lingarajg
Copy link

What changes were proposed in this pull request ?

Subprocess module allows us to execute command on the shell but usage of shell=true poses a security risk where user inputs with "rm -rf" can cause terrible things.

To avoid shell-injection vulnerabilities, subprocess can be used without shell=true, by modifying the way input is passed.
Some of the examples can be found like - https://security.openstack.org/guidelines/dg_avoid-shell-true.html

Hence, shell=false is changed in most of the places wherever shell=True is used and command is converted to a list of strings by using shlex module.

How was this patch tested?

This patch is manually tested by making changes on a existing cluster and restarting the appropriate services. Did not observe any failure in Ambari server or agent. All services were working as expected.

@@ -846,11 +847,11 @@ def adjust_jce_permissions(self, jdk_path):

cmd = " && ".join(cmds)

process = subprocess32.Popen(cmd,
process = subprocess32.Popen(shlex.split(cmd),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this part of the code it is possible to get an error due to the fact that the && character is used to chain multiple commands together in a shell environment (like bash on Linux), but when you pass your command to subprocess32.Popen it does not will be interpreted by a shell, so the && will not be recognized as a valid operator.

In addition to the command being used '*' and this can be a problem with the use of shlex, so I suggest using the glob module. As a suggestion, you have the code below that I developed

if ambari_user:
      cmds.append(self.SET_JCE_PERMISSIONS.format(ambari_user, jdk_path, configDefaults.JDK_SECURITY_DIR))
    cmds.append(self.SET_JCE_FILE_MODE.format(jdk_path, configDefaults.JDK_SECURITY_DIR, "*"))
    cmds.append(self.SET_JCE_JAR_MODE.format(jdk_path, configDefaults.JDK_SECURITY_DIR, "*.jar"))
    for cmd in cmds:
      if '*' in cmd:
          try:
              cmd_parts = shlex.split(cmd)
              files_to_process = glob.glob(cmd_parts[-1])
              
              for file_path in files_to_process:
                  cmd_parts[-1] = file_path
                  process = subprocess32.Popen(cmd_parts,
                                              stdout=subprocess32.PIPE,
                                              stdin=subprocess32.PIPE,
                                              stderr=subprocess32.PIPE,
                                              shell=False
                                              )
                  (stdoutdata, stderrdata) = process.communicate()

                  if process.returncode != 0:
                      print("Failed to change permissions for '{0}'. Stderr: {1}".format(file_path, stderrdata))
          except Exception as e:
              print("Error executing command: {0}".format(str(e)))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants