VYPR
High severity7.5NVD Advisory· Published Jan 23, 2017· Updated May 13, 2026

CVE-2016-5697

CVE-2016-5697

Description

Ruby-saml before 1.3.0 allows attackers to perform XML signature wrapping attacks via unspecified vectors.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
ruby-samlRubyGems
< 1.3.01.3.0

Affected products

1

Patches

1
a571f52171e6

Add extra validations to prevent Signature wrapping attacks

https://github.com/onelogin/ruby-samlSixto MartinJun 16, 2016via ghsa
1 file changed · +47 5
  • lib/onelogin/ruby-saml/response.rb+47 5 modified
    @@ -337,8 +337,15 @@ def validate_success_status
           # @raise [ValidationError] if soft == false and validation fails 
           #
           def validate_structure
    +        structure_error_msg = "Invalid SAML Response. Not match the saml-schema-protocol-2.0.xsd"
             unless valid_saml?(document, soft)
    -          return append_error("Invalid SAML Response. Not match the saml-schema-protocol-2.0.xsd")
    +          return append_error(structure_error_msg)
    +        end
    +
    +        unless decrypted_document.nil?
    +          unless valid_saml?(decrypted_document, soft)
    +            return append_error(structure_error_msg)
    +          end
             end
     
             true
    @@ -434,11 +441,44 @@ def validate_signed_elements
               {"ds"=>DSIG}
             )
             signed_elements = []
    +        seis = []
    +        ids = []
             signature_nodes.each do |signature_node|
               signed_element = signature_node.parent.name
               if signed_element != 'Response' && signed_element != 'Assertion'
                 return append_error("Found an unexpected Signature Element. SAML Response rejected")
               end
    +
    +          if signature_node.parent.attributes['ID'].nil?
    +            return append_error("Signed Element must contain ID. SAML Response rejected")
    +          end
    +
    +          id = signature_node.parent.attributes.get_attribute("ID").value
    +          if ids.include?(id)
    +            return append_error("Duplicated ID. SAML Response rejected")
    +          end
    +          ids.push(id)
    +
    +          # Check that reference URI matches the parent ID and no duplicate References or IDs
    +          ref = REXML::XPath.first(signature_node, ".//ds:Reference", {"ds"=>DSIG})
    +          if ref
    +            uri = ref.attributes.get_attribute("URI")
    +            if uri && !uri.value.empty?
    +              sei = uri.value[1..-1]
    +              id = signature_node.parent.attributes.get_attribute("ID").value
    +
    +              unless sei == id
    +                return append_error("Found an invalid Signed Element. SAML Response rejected")
    +              end
    +
    +              if seis.include?(sei)
    +                return append_error("Duplicated Reference URI. SAML Response rejected")
    +              end
    +
    +              seis.push(sei)
    +            end
    +          end
    +
               signed_elements << signed_element
             end
     
    @@ -614,8 +654,9 @@ def validate_signature
             # otherwise, review if the decrypted assertion contains a signature
             sig_elements = REXML::XPath.match(
               document,
    -          "/p:Response/ds:Signature]",
    -          { "p" => PROTOCOL, "ds" => DSIG }
    +          "/p:Response[@ID=$id]/ds:Signature]",
    +          { "p" => PROTOCOL, "ds" => DSIG },
    +          { 'id' => document.signed_element_id }
             )
     
             use_original = sig_elements.size == 1 || decrypted_document.nil?
    @@ -625,8 +666,9 @@ def validate_signature
             if sig_elements.nil? || sig_elements.size == 0
               sig_elements = REXML::XPath.match(
                 doc,
    -            "/p:Response/a:Assertion/ds:Signature",
    -            {"p" => PROTOCOL, "a" => ASSERTION, "ds"=>DSIG}
    +            "/p:Response/a:Assertion[@ID=$id]/ds:Signature",
    +            {"p" => PROTOCOL, "a" => ASSERTION, "ds"=>DSIG},
    +            { 'id' => doc.signed_element_id }
               )
             end
     
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.