Remote Command Execution Vulnerability - Elixir

Remote Command Execution Vulnerability - Elixir

Need

Prevent unauthorized code or command execution

Context

  • Usage of Elixir (1.10 and above) for building scalable and fault-tolerant applications
  • Usage of os.cmd for executing shell commands

Description

Non compliant code

        def run_command(input) do
  :os.cmd("echo #{input}")
end
        
        

In this code, the function 'run_command' takes user input and directly interpolates it into an OS command to be executed. This is a vulnerability because an attacker could manipulate the input to execute arbitrary commands on the OS, leading to unauthorized code execution. The function is not validating or sanitizing the input before use, which makes it susceptible to the vulnerability.

Steps

  • Validate user inputs: Check if the input is as expected. This could be a format, type, length, range, or a set of permitted values.
  • Sanitize user inputs: Remove or substitute harmful patterns in the input.
  • Instead of using external processes like :os.cmd, try using standard library calls to recreate the desired functionality.

Compliant code

        def run_command(input) do
  sanitized_input = String.replace(input, ~r/[\n\r\$()]/, "")
  case sanitized_input do
    ^sanitized_input when is_binary(sanitized_input) -> :os.cmd('echo ' <> sanitized_input)
    _ -> {:error, "Invalid input"}
  end
end
        
        

This code mitigates the vulnerability by first sanitizing the user input, removing or substituting characters that could modify the OS command. Then it verifies if the sanitized_input still is a binary string. If it isn't, it returns an error. Only if the input passes these checks, it's then used in the OS command.

References