@@ -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