@@ -322,6 +322,78 @@ class RubySamlTest < Minitest::Test
322322 logout_request_sign_test . send ( :validate_signature )
323323 end
324324 end
325+
326+ it "raise when get_params encoding differs from what this library generates" do
327+ # Use Logoutrequest only to build the SAMLRequest parameter.
328+ settings . security [ :signature_method ] = XMLSecurity ::Document ::RSA_SHA1
329+ settings . soft = false
330+ params = OneLogin ::RubySaml ::Logoutrequest . new . create_params ( settings , "RelayState" => "http://example.com" )
331+ # Assemble query string.
332+ query = OneLogin ::RubySaml ::Utils . build_query (
333+ type : 'SAMLRequest' ,
334+ data : params [ 'SAMLRequest' ] ,
335+ relay_state : params [ 'RelayState' ] ,
336+ sig_alg : params [ 'SigAlg' ] ,
337+ )
338+ # Modify the query string so that it encodes the same values,
339+ # but with different percent-encoding. Sanity-check that they
340+ # really are equialent before moving on.
341+ original_query = query . dup
342+ query . gsub! ( "example" , "ex%61mple" )
343+ refute_equal ( query , original_query )
344+ assert_equal ( CGI . unescape ( query ) , CGI . unescape ( original_query ) )
345+ # Make normalised signature based on our modified params.
346+ sign_algorithm = XMLSecurity ::BaseDocument . new . algorithm ( settings . security [ :signature_method ] )
347+ signature = settings . get_sp_key . sign ( sign_algorithm . new , query )
348+ params [ 'Signature' ] = Base64 . encode64 ( signature ) . gsub ( /\n / , "" )
349+ # Construct SloLogoutrequest and ask it to validate the signature.
350+ # It will do it incorrectly, because it will compute it based on re-encoded
351+ # query parameters, rather than their original encodings.
352+ options = { }
353+ options [ :get_params ] = params
354+ options [ :settings ] = settings
355+ logout_request_sign_test = OneLogin ::RubySaml ::SloLogoutrequest . new ( params [ 'SAMLRequest' ] , options )
356+ assert_raises ( OneLogin ::RubySaml ::ValidationError , "Invalid Signature on Logout Request" ) do
357+ logout_request_sign_test . send ( :validate_signature )
358+ end
359+ end
360+
361+ it "return true even if raw_get_params encoding differs from what this library generates" do
362+ # Use Logoutrequest only to build the SAMLRequest parameter.
363+ settings . security [ :signature_method ] = XMLSecurity ::Document ::RSA_SHA1
364+ settings . soft = false
365+ params = OneLogin ::RubySaml ::Logoutrequest . new . create_params ( settings , "RelayState" => "http://example.com" )
366+ # Assemble query string.
367+ query = OneLogin ::RubySaml ::Utils . build_query (
368+ type : 'SAMLRequest' ,
369+ data : params [ 'SAMLRequest' ] ,
370+ relay_state : params [ 'RelayState' ] ,
371+ sig_alg : params [ 'SigAlg' ] ,
372+ )
373+ # Modify the query string so that it encodes the same values,
374+ # but with different percent-encoding. Sanity-check that they
375+ # really are equialent before moving on.
376+ original_query = query . dup
377+ query . gsub! ( "example" , "ex%61mple" )
378+ refute_equal ( query , original_query )
379+ assert_equal ( CGI . unescape ( query ) , CGI . unescape ( original_query ) )
380+ # Make normalised signature based on our modified params.
381+ sign_algorithm = XMLSecurity ::BaseDocument . new . algorithm ( settings . security [ :signature_method ] )
382+ signature = settings . get_sp_key . sign ( sign_algorithm . new , query )
383+ params [ 'Signature' ] = Base64 . encode64 ( signature ) . gsub ( /\n / , "" )
384+ # Construct SloLogoutrequest and ask it to validate the signature.
385+ # Provide the altered parameter in its raw URI-encoded form,
386+ # so that we don't have to guess the value that contributed to the signature.
387+ options = { }
388+ options [ :get_params ] = params
389+ options [ :get_params ] . delete ( "RelayState" )
390+ options [ :raw_get_params ] = {
391+ "RelayState" => "http%3A%2F%2Fex%61mple.com" ,
392+ }
393+ options [ :settings ] = settings
394+ logout_request_sign_test = OneLogin ::RubySaml ::SloLogoutrequest . new ( params [ 'SAMLRequest' ] , options )
395+ assert logout_request_sign_test . send ( :validate_signature )
396+ end
325397 end
326398
327399 describe "#validate_signature with multiple idp certs" do
0 commit comments