Skip to content

Commit

Permalink
Use correct XPaths and resolve to correct elements. Block references …
Browse files Browse the repository at this point in the history
…that resolve to multiple nodes to prevent signature wrapping attacks
  • Loading branch information
pitbulk committed Sep 10, 2024
1 parent 626140b commit a7b1f2e
Showing 1 changed file with 19 additions and 6 deletions.
25 changes: 19 additions & 6 deletions lib/ruby_saml/xml/signed_document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,30 @@ def validate_signature(base64_cert, soft = true)
canon_string = noko_signed_info_element.canonicalize(canon_algorithm)
noko_sig_element.remove

# get signed info
signed_info_element = REXML::XPath.first(
sig_element,
"./ds:SignedInfo",
{ "ds" => DSIG }
)

# get inclusive namespaces
inclusive_namespaces = extract_inclusive_namespaces

# check digests
ref = REXML::XPath.first(sig_element, '//ds:Reference', {'ds'=>DSIG})
ref = REXML::XPath.first(signed_info_element, "./ds:Reference", {"ds"=>DSIG})

hashed_element = document.at_xpath('//*[@ID=$id]', nil, { 'id' => extract_signed_element_id })
reference_nodes = document.xpath("//*[@ID=$id]", nil, { 'id' => extract_signed_element_id })

if reference_nodes.length > 1 # ensures no elements with same ID to prevent signature wrapping attack.
return append_error("Digest mismatch. Duplicated ID found", soft)
end

hashed_element = reference_nodes[0]

canon_algorithm = canon_algorithm REXML::XPath.first(
ref,
'//ds:CanonicalizationMethod',
signed_info_element,
'./ds:CanonicalizationMethod',
{ 'ds' => DSIG }
)

Expand All @@ -155,7 +168,7 @@ def validate_signature(base64_cert, soft = true)
hash = digest_algorithm.digest(canon_hashed_element)
encoded_digest_value = REXML::XPath.first(
ref,
'//ds:DigestValue',
'./ds:DigestValue',
{ 'ds' => DSIG }
)
digest_value = Base64.decode64(RubySaml::Utils.element_text(encoded_digest_value))
Expand All @@ -181,7 +194,7 @@ def validate_signature(base64_cert, soft = true)
def process_transforms(ref, canon_algorithm)
transforms = REXML::XPath.match(
ref,
'//ds:Transforms/ds:Transform',
'./ds:Transforms/ds:Transform',
{ 'ds' => DSIG }
)

Expand Down

0 comments on commit a7b1f2e

Please sign in to comment.