Coordinated Disclosure Timeline

Summary

Elektra from SAP’s Converged Cloud org was susceptible to a remote code execution vulnerability. Authenticated users were able to execute arbitrary code in the context of Elektra and through this potentially access remote systems to which they would have had no access otherwise. Additionally, attackers could have sent links containing a malicious payload to authenticated Elektra users, which also would have triggered code execution.

Project

Elektra

Tested Version

618ee99

Details

Authenticated remote code execution (GHSL-2024-098)

A code injection vulnerability was found in the live search functionality of the Ruby on Rails based Elektra web application. An authenticated user can craft a search term containing Ruby code, which later flows into an eval sink which executes the code.

The entry point for a malicious search term value is the live_search method on the CacheController class:

def live_search
  data =
    begin
      api_search(services, params[:type], params[:term])
[..]
end

In this method the api_search method is called with the type and term (query) parameters. In the api_search method the passed down object_type is compared to a list of allowed types.

# This method tries to find an object by id or name via API
def api_search(service_manager, object_type, term)
  service_name, methods = service_and_methods(object_type)

  # service = object_service(service_name)
  unless service_manager.respond_to?(service_name)
    raise StandardError, "Service #{service_name} could not be found."
  end
  service = service_manager.send(service_name)
[..]

The call to service_and_methods yields a list of methods in string format on which the code will loop later on. E.g. if the type subnet is passed into service_and_methods a list containing 'find_subnet(":term")', 'subnets(name: ":term")' and 'subnets(network_id: ":term")' is returned.

Now api_search method loops over those methods and replaces the string :term with the user-controlled search term. After the replacement is done, the resulting method is appended to the static service. prefix.

def api_search(service_manager, object_type, term)
   [..]
    methods.each do |m|
      method = m.gsub(":term", term)
      found_items = eval("service.#{method}")

[..]

If an attacker chooses the subnet type, the first method string where the term will be inserted is 'find_subnet(":term")'. An input such as ") unless puts("PWNED!!! would result in the following string being executed with eval:

service.find_subnet("") unless puts("PWNED!!!")

This vulnerability was discovered with the help of CodeQL’s Code injection query.

Impact

This issue may lead to Remote Code Execution (RCE)

CVE

Credit

This issue was discovered and reported by GHSL team member @p- (Peter Stöckli).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2024-098 in any communication regarding this issue.