Fix Mastodon not correctly processing HTTP Signatures with query strings (#28476)
This commit is contained in:
		
					parent
					
						
							
								bd415af9a1
							
						
					
				
			
			
				commit
				
					
						092bb8a27a
					
				
			
		
					 3 changed files with 95 additions and 4 deletions
				
			
		|  | @ -91,14 +91,23 @@ module SignatureVerification | |||
|     raise SignatureVerificationError, "Public key not found for key #{signature_params['keyId']}" if actor.nil? | ||||
| 
 | ||||
|     signature             = Base64.decode64(signature_params['signature']) | ||||
|     compare_signed_string = build_signed_string | ||||
|     compare_signed_string = build_signed_string(include_query_string: true) | ||||
| 
 | ||||
|     return actor unless verify_signature(actor, signature, compare_signed_string).nil? | ||||
| 
 | ||||
|     # Compatibility quirk with older Mastodon versions | ||||
|     compare_signed_string = build_signed_string(include_query_string: false) | ||||
|     return actor unless verify_signature(actor, signature, compare_signed_string).nil? | ||||
| 
 | ||||
|     actor = stoplight_wrap_request { actor_refresh_key!(actor) } | ||||
| 
 | ||||
|     raise SignatureVerificationError, "Could not refresh public key #{signature_params['keyId']}" if actor.nil? | ||||
| 
 | ||||
|     compare_signed_string = build_signed_string(include_query_string: true) | ||||
|     return actor unless verify_signature(actor, signature, compare_signed_string).nil? | ||||
| 
 | ||||
|     # Compatibility quirk with older Mastodon versions | ||||
|     compare_signed_string = build_signed_string(include_query_string: false) | ||||
|     return actor unless verify_signature(actor, signature, compare_signed_string).nil? | ||||
| 
 | ||||
|     fail_with! "Verification failed for #{actor.to_log_human_identifier} #{actor.uri} using rsa-sha256 (RSASSA-PKCS1-v1_5 with SHA-256)", signed_string: compare_signed_string, signature: signature_params['signature'] | ||||
|  | @ -180,11 +189,18 @@ module SignatureVerification | |||
|     nil | ||||
|   end | ||||
| 
 | ||||
|   def build_signed_string | ||||
|   def build_signed_string(include_query_string: true) | ||||
|     signed_headers.map do |signed_header| | ||||
|       case signed_header | ||||
|       when Request::REQUEST_TARGET | ||||
|         "#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}" | ||||
|         if include_query_string | ||||
|           "#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.original_fullpath}" | ||||
|         else | ||||
|           # Current versions of Mastodon incorrectly omit the query string from the (request-target) pseudo-header. | ||||
|           # Therefore, temporarily support such incorrect signatures for compatibility. | ||||
|           # TODO: remove eventually some time after release of the fixed version | ||||
|           "#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}" | ||||
|         end | ||||
|       when '(created)' | ||||
|         raise SignatureVerificationError, 'Invalid pseudo-header (created) for rsa-sha256' unless signature_algorithm == 'hs2019' | ||||
|         raise SignatureVerificationError, 'Pseudo-header (created) used but corresponding argument missing' if signature_params['created'].blank? | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue