File: CVE-2024-45409.patch

package info (click to toggle)
ruby-saml 1.13.0-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 568 kB
  • sloc: ruby: 2,847; makefile: 4
file content (86 lines) | stat: -rw-r--r-- 3,120 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
From: ahacker1 <ahacker1@securesaml.com>
Date: Tue, 10 Sep 2024 13:12:09 -0400
Subject: Fix for critical vulnerability CVE-2024-45409: SAML authentication bypass via Incorrect XPath selector
Origin: https://github.com/SAML-Toolkits/ruby-saml/commit/4865d030cae9705ee5cdb12415c654c634093ae7,
 https://github.com/SAML-Toolkits/ruby-saml/commit/1bc447f297b769d1a9abeb619ce074bd9c410a72
Bug-Debian: https://bugs.debian.org/1081560
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2024-45409

* Use correct XPaths and resolve to correct elements

* Update xml_security.rb

* Block references that resolve to multiple nodes to prevent signature wrapping attacks

[Salvatore Bonaccorso: Cherry-pick from upstream 1bc447f297b769d1a9abeb619ce074bd9c410a72 the
 final append_error string used]
---
 lib/xml_security.rb | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/lib/xml_security.rb b/lib/xml_security.rb
index 1b1b32284e05..f731d4642d73 100644
--- a/lib/xml_security.rb
+++ b/lib/xml_security.rb
@@ -310,17 +310,29 @@ module XMLSecurity
       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 }
       )
 
@@ -330,13 +342,13 @@ module XMLSecurity
 
       digest_algorithm = algorithm(REXML::XPath.first(
         ref,
-        "//ds:DigestMethod",
+        "./ds:DigestMethod",
         { "ds" => DSIG }
       ))
       hash = digest_algorithm.digest(canon_hashed_element)
       encoded_digest_value = REXML::XPath.first(
         ref,
-        "//ds:DigestValue",
+        "./ds:DigestValue",
         { "ds" => DSIG }
       )
       digest_value = Base64.decode64(OneLogin::RubySaml::Utils.element_text(encoded_digest_value))
@@ -362,7 +374,7 @@ module XMLSecurity
     def process_transforms(ref, canon_algorithm)
       transforms = REXML::XPath.match(
         ref,
-        "//ds:Transforms/ds:Transform",
+        "./ds:Transforms/ds:Transform",
         { "ds" => DSIG }
       )
 
-- 
2.45.2