@@ -312,17 +312,30 @@ def validate_signature(base64_cert, soft = true)
312
312
canon_string = noko_signed_info_element . canonicalize ( canon_algorithm )
313
313
noko_sig_element . remove
314
314
315
+ # get signed info
316
+ signed_info_element = REXML ::XPath . first (
317
+ sig_element ,
318
+ "./ds:SignedInfo" ,
319
+ { "ds" => DSIG }
320
+ )
321
+
315
322
# get inclusive namespaces
316
323
inclusive_namespaces = extract_inclusive_namespaces
317
324
318
325
# 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 } )
320
327
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 ]
322
335
323
336
canon_algorithm = canon_algorithm REXML ::XPath . first (
324
- ref ,
325
- '/ /ds:CanonicalizationMethod' ,
337
+ signed_info_element ,
338
+ '. /ds:CanonicalizationMethod' ,
326
339
{ "ds" => DSIG }
327
340
)
328
341
@@ -332,13 +345,13 @@ def validate_signature(base64_cert, soft = true)
332
345
333
346
digest_algorithm = algorithm ( REXML ::XPath . first (
334
347
ref ,
335
- "/ /ds:DigestMethod" ,
348
+ ". /ds:DigestMethod" ,
336
349
{ "ds" => DSIG }
337
350
) )
338
351
hash = digest_algorithm . digest ( canon_hashed_element )
339
352
encoded_digest_value = REXML ::XPath . first (
340
353
ref ,
341
- "/ /ds:DigestValue" ,
354
+ ". /ds:DigestValue" ,
342
355
{ "ds" => DSIG }
343
356
)
344
357
digest_value = Base64 . decode64 ( OneLogin ::RubySaml ::Utils . element_text ( encoded_digest_value ) )
@@ -364,7 +377,7 @@ def validate_signature(base64_cert, soft = true)
364
377
def process_transforms ( ref , canon_algorithm )
365
378
transforms = REXML ::XPath . match (
366
379
ref ,
367
- "/ /ds:Transforms/ds:Transform" ,
380
+ ". /ds:Transforms/ds:Transform" ,
368
381
{ "ds" => DSIG }
369
382
)
370
383
0 commit comments