Skip to content

Latest commit

 

History

History
373 lines (270 loc) · 18.3 KB

File metadata and controls

373 lines (270 loc) · 18.3 KB

Ruby SAML Migration Guide

Upgrading from 1.x to 2.0.0

IMPORTANT: Please read this section carefully as it contains breaking changes!

Before upgrading

Before attempting to upgrade to 2.0.0:

  • Upgrade your project to minimum Ruby 3.0, JRuby 9.4, or TruffleRuby 22.
  • Upgrade RubySaml to 1.17.x.
  • In RubySaml 1.17.x, if you were using the SHA-1 default behavior, change your settings to use SHA-256 as per below:
# Set this in RubySaml 1.17.x, can be removed when upgrading to 2.0.0
settings.idp_cert_fingerprint_algorithm = XMLSecurity::Document::SHA256
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
settings.security[:digest_method] = XMLSecurity::Document::SHA256

JRuby users should upgrade to JRuby 1.19 or later

JRuby users should upgrade to Nokogiri gem version 1.19 or later, to avoid this Nokogiri issue affecting how XML is generated on JRuby. This issue is likely not critical for most IdPs, but since it is not tested, it is recommended to upgrade.

Root "OneLogin" namespace changed to "RubySaml"

RubySaml version 2.0.0 changes the root namespace from OneLogin::RubySaml:: to just RubySaml::. Please remove OneLogin:: and onelogin/ everywhere in your codebase. Aside from this namespace change, the class names themselves have intentionally been kept the same.

Note that the project folder structure has also been updated accordingly. Notably, the directory lib/onelogin/schemas is now lib/ruby_saml/schemas.

For backward compatibility, the alias OneLogin = Object has been set, so OneLogin::RubySaml:: will still work as before. This alias will be removed in RubySaml version 3.0.0.

Deprecation and removal of "XMLSecurity" namespace

RubySaml version 2.0.0 deprecates the ::XMLSecurity namespace and the following classes:

Removed Class Replacement Module & Method
XMLSecurity::BaseDocument (none)
XMLSecurity::Document RubySaml::XML::DocumentSigner.sign_document
XMLSecurity::SignedDocument Will be replaced with RubySaml::XML::SignedDocumentValidator.validate_document

If your application does not already define the XMLSecurity namespace (e.g. from another gem), these old classes will be shimmed to raise a deprecation warning or NoMethodError when used.

The new modules in the RubySaml::XML namespace provide similar functionality as the deprecated classes, but are based on Nokogiri instead of REXML.

Security: Change default hashing algorithm to SHA-256 (was SHA-1)

For security reasons, RubySaml version 2.0.0 uses SHA-256 as its default hashing algorithm everywhere instead of the now-obsolete SHA-1. This affects:

  • The default signature and digest algorithms used when generating SP metadata.
  • The default signature algorithm used when generating SP messages such as AuthnRequests.
  • The :idp_cert_fingerprint of IdP metadata as generated by RubySaml::IdpMetadataParser.

If you see any signature or fingerprint mismatch errors after upgrading to RubySaml 2.0.0, this change is likely the reason. To preserve the old insecure SHA-1 behavior (not recommended), you may set RubySaml::Settings as follows:

# Preserve RubySaml 1.x insecure SHA-1 behavior
settings.idp_cert_fingerprint_algorithm = RubySaml::XML::SHA1
settings.security[:digest_method] = RubySaml::XML::SHA1
settings.security[:signature_method] = RubySaml::XML::RSA_SHA1

Replacement of REXML with Nokogiri

RubySaml 1.x used a combination of REXML and Nokogiri for XML parsing and generation. In 2.0.0, REXML has been replaced with Nokogiri. This change should be transparent to most users, however, see note about Custom Metadata Fields below.

Custom Metadata Fields now use Nokogiri XML Builder

If you have added custom fields to your SP metadata generation by overriding the RubySaml::Metadata#add_extras method, you will need to update your code to use Nokogiri::XML::Builder format instead of REXML. Here is an example of the new format:

class MyMetadata < RubySaml::Metadata
  private

  def add_extras(xml, _settings)
    xml['md'].ContactPerson('contactType' => 'technical') do
      xml['md'].GivenName('ACME SAML Team')
      xml['md'].EmailAddress('saml@acme.com')
    end
  end
end

Behavior change of double_quote_xml_attribute_values setting

RubySaml now always uses double quotes for attribute values when generating XML. The settings.double_quote_xml_attribute_values parameter now always behaves as true, and will be removed in RubySaml 3.0.0.

The reasons for this change are:

  • RubySaml will use Nokogiri instead of REXML to generate XML. Nokogiri does not support generating XML with single quotes.
  • Double-quoted XML attributes are more commonly used than single quotes. There are no known SAML clients which cannot support double-quoted XML.

Removal of embed_sign setting

The deprecated settings.security[:embed_sign] parameter has been removed. If you were using it, please instead switch to using both the settings.idp_sso_service_binding and settings.idp_slo_service_binding parameters as show below. (This new syntax is supported on version 1.13.0 and later.)

# Replace settings.security[:embed_sign] = true with
settings.idp_sso_service_binding = :post
settings.idp_slo_service_binding = :post

# Replace settings.security[:embed_sign] = false with
settings.idp_sso_service_binding = :redirect
settings.idp_slo_service_binding = :redirect

For clarity, the default value of both parameters is :redirect if they are not set.

Change to message UUID prefix customization

On SP-originated messages (Authrequest, Logoutrequest, Logoutresponse), RubySaml generates the uuid (aliased to request_id / response_id) using the _ character as a default prefix, for example _a1b3c5d7-9f1e-3d5c-7b1a-9f1e3d5c7b1a. In RubySaml versions prior to 2.0.0, it was possible to change this default prefix by either RubySaml::Utils.set_prefix or by mutating the RubySaml::Utils::UUID_PREFIX constant (which was what .set_prefix did.) In RubySaml 2.0.0, this prefix is now set using settings.sp_uuid_prefix:

# Change the default prefix from `_` to `my_id_`
settings.sp_uuid_prefix = 'my_id_'

# Create the AuthNRequest message
request = RubySaml::Authrequest.new
request.create(settings)
request.uuid #=> "my_id_a1b3c5d7-9f1e-3d5c-7b1a-9f1e3d5c7b1a"

A side-effect of this change is that the uuid of the Authrequest, Logoutrequest, and Logoutresponse classes now is nil until the #create method is called (previously, it was set in the initializer.) After calling #create for the first time the uuid will not change, even if a Settings object with a different sp_uuid_prefix is passed-in on subsequent calls.

Deprecation of compression settings

The settings.compress_request and settings.compress_response parameters have been deprecated and are no longer functional. They will be removed in RubySaml 3.0.0. Please remove compress_request and compress_response everywhere within your project code.

The SAML SP request/response message compression behavior is now controlled automatically by the settings.idp_sso_service_binding and settings.idp_slo_service_binding parameters respectively: HTTP-Redirect will always use compression, while HTTP-POST will not. For clarity, here "compression" is used to make redirect URLs which contain SAML messages be shorter. For POST messages, compression may be achieved by enabling Content-Encoding: gzip on your webserver.

Deprecation of IdP certificate fingerprint settings

The settings.idp_cert_fingerprint and settings.idp_cert_fingerprint_algorithm are deprecated and will be removed in RubySaml 3.0.0. Please use settings.idp_cert or settings.idp_cert_multi instead.

The reasons for this deprecation are:

  • Fingerprint cannot be used with HTTP-Redirect binding
  • Fingerprint is theoretically susceptible to collision attacks.

Other settings deprecations

The following parameters in RubySaml::Settings are deprecated and will be removed in RubySaml 3.0.0:

  • #issuer is deprecated and replaced 1:1 by #sp_entity_id
  • #idp_sso_target_url is deprecated and replaced 1:1 by #idp_sso_service_url
  • #idp_slo_target_url is deprecated and replaced 1:1 by #idp_slo_service_url
  • #assertion_consumer_logout_service_url is deprecated and replaced 1:1 by #single_logout_service_url
  • #assertion_consumer_logout_service_binding is deprecated and replaced 1:1 by #single_logout_service_binding
  • #certificate_new is deprecated and replaced by #sp_cert_multi. Refer to documentation as #sp_cert_multi has a different value type than #certificate_new.

Minor changes to Util#format_cert and #format_private_key

Version 2.0.0 standardizes how RubySaml reads and formats certificate and private key PEM strings. In general, version 2.0.0 is more permissive than 1.x, and the changes are not anticipated to affect most users. Please note the change affects parameters such #idp_cert and #certificate, as well as the RubySaml::Utils#format_cert and #format_private_key methods. Specifically:

# Input value RubySaml 2.0.0 RubySaml 1.x
1 Input contains a bad (e.g. non-base64) PEM Skip PEM formatting Return a bad PEM
2 Input contains \r character(s) Strip out all \r character(s) and format as PEM Skip PEM formatting
3 PEM header other than CERTIFICATE or PRIVATE KEY Format if header ends in CERTIFICATE or PRIVATE KEY Skip PEM formatting
4 #format_cert given PRIVATE KEY (and vice-versa) Ignore PEMs of incorrect type Return a bad PEM
5 Text outside header/footer values Strip out text outside header/footer values Skip PEM formatting
6 Input non-ASCII characters Ignore non-ASCII chars if they are outside the PEM Skip PEM formatting
7 #format_cert input contains mix of good/bad certs Return only good cert PEMs (joined with \n) Return good and bad certs

Notes

  • Case 3: For example, -----BEGIN TRUSTED X509 CERTIFICATE----- is now considered a valid header as an input, but it will be formatted to -----BEGIN CERTIFICATE----- in the output. As a special case, in both 2.0.0 and 1.x, if RSA PRIVATE KEY is present in the input string, the RSA prefix will be preserved in the output.
  • Case 5: When formatting multiple certificates in one string (i.e. a certificate chain), text present between the footer and header of two different certificates will also be stripped out.
  • Case 7: If no valid certificates are found, the entire original string will be returned.

Upgrading from 1.17.x to 1.18.0

Version 1.18.0 changes the way the toolkit validates SAML signatures. There is a new order how validation happens in the toolkit and also the toolkit by default will check malformed doc when parsing a SAML Message (settings.check_malformed_doc).

The SignedDocument class defined at xml_security.rb experienced several changes. We don't expect compatibilty issues if you use the main methods offered by ruby-saml, but if you use a fork or customized usage, is possible that you need to adapt your code.

Upgrading from 1.12.x to 1.13.0

Version 1.13.0 adds settings.idp_sso_service_binding and settings.idp_slo_service_binding, and deprecates settings.security[:embed_sign]. If specified, new binding parameters will be used in place of :embed_sign to determine how to handle SAML message signing (HTTP-POST embeds signature and HTTP-Redirect does not.)

In addition, the IdpMetadataParser#parse, #parse_to_hash and #parse_to_array methods now retrieve idp_sso_service_binding and idp_slo_service_binding.

Lastly, for convenience you may now use the Symbol aliases :post and :redirect for any settings.*_binding parameter.

Upgrading from 1.11.x to 1.12.0

Version 1.12.0 adds support for gcm algorithm and change/adds specific error messages for signature validations

idp_sso_target_url and idp_slo_target_url attributes of the Settings class deprecated in favor of idp_sso_service_url and idp_slo_service_url. The IdpMetadataParser#parse, #parse_to_hash and #parse_to_array methods now retrieve SSO URL and SLO URL endpoints with idp_sso_service_url and idp_slo_service_url (previously idp_sso_target_url and idp_slo_target_url respectively).

Upgrading from 1.10.x to 1.11.0

Version 1.11.0 deprecates the use of settings.issuer in favour of settings.sp_entity_id. There are two new security settings: settings.security[:check_idp_cert_expiration] and settings.security[:check_sp_cert_expiration] (both false by default) that check if the IdP or SP X.509 certificate has expired, respectively.

Version 1.10.2 includes the valid_until attribute in parsed IdP metadata.

Version 1.10.1 improves Ruby 1.8.7 support.

Upgrading from 1.9.0 to 1.10.0

Version 1.10.0 improves IdpMetadataParser to allow parse multiple IDPSSODescriptor, Add Subject support on AuthNRequest to allow SPs provide info to the IdP about the user to be authenticated and updates the format_cert method to accept certs with /\x0d/

Upgrading from 1.8.0 to 1.9.0

Version 1.9.0 better supports Ruby 2.4+ and JRuby 9.2.0.0. Settings initialization now has a second parameter, keep_security_settings (default: false), which saves security settings attributes that are not explicitly overridden, if set to true.

Upgrading from 1.7.x to 1.8.0

On Version 1.8.0, creating AuthRequests/LogoutRequests/LogoutResponses with nil RelayState param will not generate a URL with an empty RelayState parameter anymore. It also changes the invalid audience error message.

Upgrading from 1.6.0 to 1.7.0

Version 1.7.0 is a recommended update for all Ruby SAML users as it includes a fix for the CVE-2017-11428 vulnerability.

Upgrading from 1.5.0 to 1.6.0

Version 1.6.0 changes the preferred way to construct instances of Logoutresponse and SloLogoutrequest. Previously the SAMLResponse, RelayState, and SigAlg parameters of these message types were provided via the initializer's options[:get_params] parameter. Unfortunately this can result in incompatibility with other SAML implementations; signatures are specified to be computed based on the sender's URI-encoding of the message, which can differ from that of Ruby SAML. In particular, Ruby SAML's URI-encoding does not match that of Microsoft ADFS, so messages from ADFS can fail signature validation.

The new preferred way to provide SAMLResponse, RelayState, and SigAlg is via the options[:raw_get_params] parameter. For example:

# In this example `query_params` is assumed to contain decoded query parameters,
# and `raw_query_params` is assumed to contain encoded query parameters as sent by the IDP.
settings = {
  settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
  settings.soft = false
}
options = {
  get_params: {
    "Signature" => query_params["Signature"],
  },
  raw_get_params: {
    "SAMLRequest" => raw_query_params["SAMLRequest"],
    "SigAlg" => raw_query_params["SigAlg"],
    "RelayState" => raw_query_params["RelayState"],
  },
}
slo_logout_request = OneLogin::RubySaml::SloLogoutrequest.new(query_params["SAMLRequest"], settings, options)
raise "Invalid Logout Request" unless slo_logout_request.is_valid?

The old form is still supported for backward compatibility, but all Ruby SAML users should prefer options[:raw_get_params] where possible to ensure compatibility with other SAML implementations.

Upgrading from 1.4.2 to 1.4.3

Version 1.4.3 introduces Recipient validation of SubjectConfirmation elements. The 'Recipient' value is compared with the settings.assertion_consumer_service_url value.

If you want to skip that validation, add the :skip_recipient_check option to the initialize method of the Response object.

Parsing metadata that contains more than one certificate will propagate the idp_cert_multi property rather than idp_cert. See signature validation section for details.

Upgrading from 1.3.x to 1.4.x

Version 1.4.0 is a recommended update for all Ruby SAML users as it includes security improvements.

Upgrading from 1.2.x to 1.3.x

Version 1.3.0 is a recommended update for all Ruby SAML users as it includes security fixes. It adds security improvements in order to prevent Signature wrapping attacks. CVE-2016-5697

Upgrading from 1.1.x to 1.2.x

Version 1.2 adds IDP metadata parsing improvements, uuid deprecation in favour of SecureRandom, refactor error handling and some minor improvements.

There is no compatibility issue detected.

For more details, please review CHANGELOG.md.

Upgrading from 1.0.x to 1.1.x

Version 1.1 adds some improvements on signature validation and solves some namespace conflicts.

Upgrading from 0.9.x to 1.0.x

Version 1.0 is a recommended update for all Ruby SAML users as it includes security fixes.

Version 1.0 adds security improvements like entity expansion limitation, more SAML message validations, and other important improvements like decrypt support.

Important Changes

Please note the get_idp_metadata method raises an exception when it is not able to fetch the idp metadata, so review your integration if you are using this functionality.

Upgrading from 0.8.x to 0.9.x

Version 0.9 adds many new features and improvements.

Upgrading from 0.7.x to 0.8.x

Version 0.8.x changes the namespace of the gem from OneLogin::Saml to OneLogin::RubySaml. Please update your implementations of the gem accordingly.