@@ -310,17 +310,29 @@ def validate_signature(base64_cert, soft = true)
310
310
canon_string = noko_signed_info_element . canonicalize ( canon_algorithm )
311
311
noko_sig_element . remove
312
312
313
+ # get signed info
314
+ signed_info_element = REXML ::XPath . first (
315
+ sig_element ,
316
+ "./ds:SignedInfo" ,
317
+ { "ds" => DSIG }
318
+ )
313
319
# get inclusive namespaces
314
320
inclusive_namespaces = extract_inclusive_namespaces
315
321
316
322
# check digests
317
- ref = REXML ::XPath . first ( sig_element , "/ /ds:Reference" , { "ds" => DSIG } )
323
+ ref = REXML ::XPath . first ( signed_info_element , ". /ds:Reference" , { "ds" => DSIG } )
318
324
319
- hashed_element = document . at_xpath ( "//*[@ID=$id]" , nil , { 'id' => extract_signed_element_id } )
325
+ reference_nodes = document . xpath ( "//*[@ID=$id]" , nil , { 'id' => extract_signed_element_id } )
326
+
327
+ if reference_nodes . length > 1 # ensures no elements with same ID to prevent signature wrapping attack.
328
+ return append_error ( "Digest Mismatch" , soft )
329
+ end
330
+
331
+ hashed_element = reference_nodes [ 0 ]
320
332
321
333
canon_algorithm = canon_algorithm REXML ::XPath . first (
322
- ref ,
323
- '/ /ds:CanonicalizationMethod' ,
334
+ signed_info_element ,
335
+ '. /ds:CanonicalizationMethod' ,
324
336
{ "ds" => DSIG }
325
337
)
326
338
@@ -330,13 +342,13 @@ def validate_signature(base64_cert, soft = true)
330
342
331
343
digest_algorithm = algorithm ( REXML ::XPath . first (
332
344
ref ,
333
- "/ /ds:DigestMethod" ,
345
+ ". /ds:DigestMethod" ,
334
346
{ "ds" => DSIG }
335
347
) )
336
348
hash = digest_algorithm . digest ( canon_hashed_element )
337
349
encoded_digest_value = REXML ::XPath . first (
338
350
ref ,
339
- "/ /ds:DigestValue" ,
351
+ ". /ds:DigestValue" ,
340
352
{ "ds" => DSIG }
341
353
)
342
354
digest_value = Base64 . decode64 ( OneLogin ::RubySaml ::Utils . element_text ( encoded_digest_value ) )
@@ -362,7 +374,7 @@ def validate_signature(base64_cert, soft = true)
362
374
def process_transforms ( ref , canon_algorithm )
363
375
transforms = REXML ::XPath . match (
364
376
ref ,
365
- "/ /ds:Transforms/ds:Transform" ,
377
+ ". /ds:Transforms/ds:Transform" ,
366
378
{ "ds" => DSIG }
367
379
)
368
380
0 commit comments