Skip to content

Commit 1ec5392

Browse files
committed
Release 1.12.3 to include critical vulnerability CVE-2024-45409 fix
1 parent bbb4fb6 commit 1ec5392

File tree

3 files changed

+24
-8
lines changed

3 files changed

+24
-8
lines changed

changelog.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# RubySaml Changelog
22

3+
### 1.12.3 (Sep 10, 2024)
4+
* Fix for critical vulnerability CVE-2024-45409: SAML authentication bypass via Incorrect XPath selector
5+
36
### 1.12.2 (Apr 08, 2022)
47
* [575](https://github.com/onelogin/ruby-saml/pull/575) Fix SloLogoutresponse bug on LogoutRequest
58

lib/onelogin/ruby-saml/version.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module OneLogin
22
module RubySaml
3-
VERSION = '1.12.2'
3+
VERSION = '1.12.3'
44
end
55
end

lib/xml_security.rb

+20-7
Original file line numberDiff line numberDiff line change
@@ -312,17 +312,30 @@ def validate_signature(base64_cert, soft = true)
312312
canon_string = noko_signed_info_element.canonicalize(canon_algorithm)
313313
noko_sig_element.remove
314314

315+
# get signed info
316+
signed_info_element = REXML::XPath.first(
317+
sig_element,
318+
"./ds:SignedInfo",
319+
{ "ds" => DSIG }
320+
)
321+
315322
# get inclusive namespaces
316323
inclusive_namespaces = extract_inclusive_namespaces
317324

318325
# check digests
319-
ref = REXML::XPath.first(sig_element, "//ds:Reference", {"ds"=>DSIG})
326+
ref = REXML::XPath.first(signed_info_element, "./ds:Reference", {"ds"=>DSIG})
320327

321-
hashed_element = document.at_xpath("//*[@ID=$id]", nil, { 'id' => extract_signed_element_id })
328+
reference_nodes = document.xpath("//*[@ID=$id]", nil, { 'id' => extract_signed_element_id })
329+
330+
if reference_nodes.length > 1 # ensures no elements with same ID to prevent signature wrapping attack.
331+
return append_error("Duplicated IDs found", soft)
332+
end
333+
334+
hashed_element = reference_nodes[0]
322335

323336
canon_algorithm = canon_algorithm REXML::XPath.first(
324-
ref,
325-
'//ds:CanonicalizationMethod',
337+
signed_info_element,
338+
'./ds:CanonicalizationMethod',
326339
{ "ds" => DSIG }
327340
)
328341

@@ -332,13 +345,13 @@ def validate_signature(base64_cert, soft = true)
332345

333346
digest_algorithm = algorithm(REXML::XPath.first(
334347
ref,
335-
"//ds:DigestMethod",
348+
"./ds:DigestMethod",
336349
{ "ds" => DSIG }
337350
))
338351
hash = digest_algorithm.digest(canon_hashed_element)
339352
encoded_digest_value = REXML::XPath.first(
340353
ref,
341-
"//ds:DigestValue",
354+
"./ds:DigestValue",
342355
{ "ds" => DSIG }
343356
)
344357
digest_value = Base64.decode64(OneLogin::RubySaml::Utils.element_text(encoded_digest_value))
@@ -364,7 +377,7 @@ def validate_signature(base64_cert, soft = true)
364377
def process_transforms(ref, canon_algorithm)
365378
transforms = REXML::XPath.match(
366379
ref,
367-
"//ds:Transforms/ds:Transform",
380+
"./ds:Transforms/ds:Transform",
368381
{ "ds" => DSIG }
369382
)
370383

0 commit comments

Comments
 (0)