Skip to content

Commit 9fc2e66

Browse files
committed
Merge remote-tracking branch 'remotes/origin/master' into fix-clock-drift
2 parents 19327b4 + 993fc10 commit 9fc2e66

24 files changed

Lines changed: 813 additions & 385 deletions

.travis.yml

Lines changed: 0 additions & 48 deletions
This file was deleted.

changelog.md renamed to CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# RubySaml Changelog
1+
# Ruby SAML Changelog
22

33
### 1.12.2 (Apr 08, 2021)
44
* [575](https://github.com/onelogin/ruby-saml/pull/575) Fix SloLogoutresponse bug on LogoutRequest

README.md

Lines changed: 115 additions & 150 deletions
Large diffs are not rendered by default.

UPGRADING.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Ruby SAML Migration Guide
2+
3+
## Upgrading from 1.11.x to 1.12.0
4+
5+
Version `1.12.0` adds support for gcm algorithm and
6+
change/adds specific error messages for signature validations
7+
8+
`idp_sso_target_url` and `idp_slo_target_url` attributes of the Settings class deprecated
9+
in favor of `idp_sso_service_url` and `idp_slo_service_url`. In IDPMetadataParser,
10+
`parse`, `parse_to_hash` and `parse_to_array` methods now retrieve
11+
SSO URL and SLO URL endpoints with `idp_sso_service_url` and `idp_slo_service_url`
12+
(previously `idp_sso_target_url` and `idp_slo_target_url` respectively).
13+
14+
## Upgrading from 1.10.x to 1.11.0
15+
16+
Version `1.11.0` deprecates the use of `settings.issuer` in favour of `settings.sp_entity_id`.
17+
There are two new security settings: `settings.security[:check_idp_cert_expiration]` and
18+
`settings.security[:check_sp_cert_expiration]` (both false by default) that check if the
19+
IdP or SP X.509 certificate has expired, respectively.
20+
21+
Version `1.10.2` includes the `valid_until` attribute in parsed IdP metadata.
22+
23+
Version `1.10.1` improves Ruby 1.8.7 support.
24+
25+
## Upgrading from 1.9.0 to 1.10.0
26+
27+
Version `1.10.0` improves IdpMetadataParser to allow parse multiple IDPSSODescriptor,
28+
Add Subject support on AuthNRequest to allow SPs provide info to the IdP about the user
29+
to be authenticated and updates the format_cert method to accept certs with /\x0d/
30+
31+
## Upgrading from 1.8.0 to 1.9.0
32+
33+
Version `1.9.0` better supports Ruby 2.4+ and JRuby 9.2.0.0. `Settings` initialization
34+
now has a second parameter, `keep_security_settings` (default: false), which saves security
35+
settings attributes that are not explicitly overridden, if set to true.
36+
37+
## Upgrading from 1.7.x to 1.8.0
38+
39+
On Version `1.8.0`, creating AuthRequests/LogoutRequests/LogoutResponses with nil RelayState
40+
param will not generate a URL with an empty RelayState parameter anymore. It also changes
41+
the invalid audience error message.
42+
43+
## Upgrading from 1.6.0 to 1.7.0
44+
45+
Version `1.7.0` is a recommended update for all Ruby SAML users as it includes a fix for
46+
the [CVE-2017-11428](https://www.cvedetails.com/cve/CVE-2017-11428/) vulnerability.
47+
48+
## Upgrading from 1.5.0 to 1.6.0
49+
50+
Version `1.6.0` changes the preferred way to construct instances of `Logoutresponse` and
51+
`SloLogoutrequest`. Previously the _SAMLResponse_, _RelayState_, and _SigAlg_ parameters
52+
of these message types were provided via the constructor's `options[:get_params]` parameter.
53+
Unfortunately this can result in incompatibility with other SAML implementations; signatures
54+
are specified to be computed based on the _sender's_ URI-encoding of the message, which can
55+
differ from that of Ruby SAML. In particular, Ruby SAML's URI-encoding does not match that
56+
of Microsoft ADFS, so messages from ADFS can fail signature validation.
57+
58+
The new preferred way to provide _SAMLResponse_, _RelayState_, and _SigAlg_ is via the
59+
`options[:raw_get_params]` parameter. For example:
60+
61+
```ruby
62+
# In this example `query_params` is assumed to contain decoded query parameters,
63+
# and `raw_query_params` is assumed to contain encoded query parameters as sent by the IDP.
64+
settings = {
65+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
66+
settings.soft = false
67+
}
68+
options = {
69+
get_params: {
70+
"Signature" => query_params["Signature"],
71+
},
72+
raw_get_params: {
73+
"SAMLRequest" => raw_query_params["SAMLRequest"],
74+
"SigAlg" => raw_query_params["SigAlg"],
75+
"RelayState" => raw_query_params["RelayState"],
76+
},
77+
}
78+
slo_logout_request = OneLogin::RubySaml::SloLogoutrequest.new(query_params["SAMLRequest"], settings, options)
79+
raise "Invalid Logout Request" unless slo_logout_request.is_valid?
80+
```
81+
82+
The old form is still supported for backward compatibility, but all Ruby SAML users
83+
should prefer `options[:raw_get_params]` where possible to ensure compatibility with
84+
other SAML implementations.
85+
86+
## Upgrading from 1.4.2 to 1.4.3
87+
88+
Version `1.4.3` introduces Recipient validation of SubjectConfirmation elements.
89+
The 'Recipient' value is compared with the settings.assertion_consumer_service_url
90+
value.
91+
92+
If you want to skip that validation, add the :skip_recipient_check option to the
93+
initialize method of the Response object.
94+
95+
Parsing metadata that contains more than one certificate will propagate the
96+
idp_cert_multi property rather than idp_cert. See [signature validation
97+
section](#signature-validation) for details.
98+
99+
## Upgrading from 1.3.x to 1.4.x
100+
101+
Version `1.4.0` is a recommended update for all Ruby SAML users as it includes security improvements.
102+
103+
## Upgrading from 1.2.x to 1.3.x
104+
105+
Version `1.3.0` is a recommended update for all Ruby SAML users as it includes security fixes.
106+
It adds security improvements in order to prevent Signature wrapping attacks.
107+
[CVE-2016-5697](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5697)
108+
109+
## Upgrading from 1.1.x to 1.2.x
110+
111+
Version `1.2` adds IDP metadata parsing improvements, uuid deprecation in favour of SecureRandom,
112+
refactor error handling and some minor improvements.
113+
114+
There is no compatibility issue detected.
115+
116+
For more details, please review [CHANGELOG.md](CHANGELOG.md).
117+
118+
## Upgrading from 1.0.x to 1.1.x
119+
120+
Version `1.1` adds some improvements on signature validation and solves some namespace conflicts.
121+
122+
## Upgrading from 0.9.x to 1.0.x
123+
124+
Version `1.0` is a recommended update for all Ruby SAML users as it includes security fixes.
125+
126+
Version `1.0` adds security improvements like entity expansion limitation, more SAML message validations, and other important improvements like decrypt support.
127+
128+
### Important Changes
129+
130+
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.
131+
132+
## Upgrading from 0.8.x to 0.9.x
133+
134+
Version `0.9` adds many new features and improvements.
135+
136+
## Upgrading from 0.7.x to 0.8.x
137+
138+
Version `0.8.x` changes the namespace of the gem from `OneLogin::Saml` to `OneLogin::RubySaml`. Please update your implementations of the gem accordingly.

lib/onelogin/ruby-saml/authrequest.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def create_params(settings, params={})
7373
base64_request = encode(request)
7474
request_params = {"SAMLRequest" => base64_request}
7575

76-
if settings.security[:authn_requests_signed] && !settings.security[:embed_sign] && settings.private_key
76+
if settings.idp_sso_service_binding == Utils::BINDINGS[:redirect] && settings.security[:authn_requests_signed] && settings.private_key
7777
params['SigAlg'] = settings.security[:signature_method]
7878
url_string = OneLogin::RubySaml::Utils.build_query(
7979
:type => 'SAMLRequest',
@@ -179,8 +179,7 @@ def create_xml_document(settings)
179179
end
180180

181181
def sign_document(document, settings)
182-
# embed signature
183-
if settings.security[:authn_requests_signed] && settings.private_key && settings.certificate && settings.security[:embed_sign]
182+
if settings.idp_sso_service_binding == Utils::BINDINGS[:post] && settings.security[:authn_requests_signed] && settings.private_key && settings.certificate
184183
private_key = settings.get_sp_key
185184
cert = settings.get_sp_cert
186185
document.sign_document(private_key, cert, settings.security[:signature_method], settings.security[:digest_method])

lib/onelogin/ruby-saml/idp_metadata_parser.rb

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,10 @@ def parse(idp_metadata, options = {})
119119

120120
unless parsed_metadata[:cache_duration].nil?
121121
cache_valid_until_timestamp = OneLogin::RubySaml::Utils.parse_duration(parsed_metadata[:cache_duration])
122-
if parsed_metadata[:valid_until].nil? || cache_valid_until_timestamp < Time.parse(parsed_metadata[:valid_until], Time.now.utc).to_i
123-
parsed_metadata[:valid_until] = Time.at(cache_valid_until_timestamp).utc.strftime("%Y-%m-%dT%H:%M:%SZ")
122+
unless cache_valid_until_timestamp.nil?
123+
if parsed_metadata[:valid_until].nil? || cache_valid_until_timestamp < Time.parse(parsed_metadata[:valid_until], Time.now.utc).to_i
124+
parsed_metadata[:valid_until] = Time.at(cache_valid_until_timestamp).utc.strftime("%Y-%m-%dT%H:%M:%SZ")
125+
end
124126
end
125127
end
126128
# Remove the cache_duration because on the settings
@@ -225,7 +227,9 @@ def to_hash(options = {})
225227
:idp_entity_id => @entity_id,
226228
:name_identifier_format => idp_name_id_format,
227229
:idp_sso_service_url => single_signon_service_url(options),
230+
:idp_sso_service_binding => single_signon_service_binding(options[:sso_binding]),
228231
:idp_slo_service_url => single_logout_service_url(options),
232+
:idp_slo_service_binding => single_logout_service_binding(options[:slo_binding]),
229233
:idp_slo_response_service_url => single_logout_response_service_url(options),
230234
:idp_attribute_names => attribute_names,
231235
:idp_cert => nil,
@@ -275,8 +279,8 @@ def single_signon_service_binding(binding_priority = nil)
275279
if binding_priority
276280
values = nodes.map(&:value)
277281
binding_priority.detect{ |binding| values.include? binding }
278-
else
279-
nodes.first.value if nodes.any?
282+
elsif nodes.any?
283+
nodes.first.value
280284
end
281285
end
282286

@@ -307,8 +311,8 @@ def single_logout_service_binding(binding_priority = nil)
307311
if binding_priority
308312
values = nodes.map(&:value)
309313
binding_priority.detect{ |binding| values.include? binding }
310-
else
311-
nodes.first.value if nodes.any?
314+
elsif nodes.any?
315+
nodes.first.value
312316
end
313317
end
314318

@@ -421,10 +425,10 @@ def merge_certificates_into(parsed_metadata)
421425
parsed_metadata[:idp_cert_fingerprint_algorithm]
422426
)
423427
end
424-
else
425-
# symbolize keys of certificates and pass it on
426-
parsed_metadata[:idp_cert_multi] = Hash[certificates.map { |k, v| [k.to_sym, v] }]
427428
end
429+
430+
# symbolize keys of certificates and pass it on
431+
parsed_metadata[:idp_cert_multi] = Hash[certificates.map { |k, v| [k.to_sym, v] }]
428432
end
429433

430434
def certificates_has_one(key)

lib/onelogin/ruby-saml/logoutrequest.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ def create_params(settings, params={})
7070
base64_request = encode(request)
7171
request_params = {"SAMLRequest" => base64_request}
7272

73-
if settings.security[:logout_requests_signed] && !settings.security[:embed_sign] && settings.private_key
74-
params['SigAlg'] = settings.security[:signature_method]
73+
if settings.idp_slo_service_binding == Utils::BINDINGS[:redirect] && settings.security[:logout_requests_signed] && settings.private_key
74+
params['SigAlg'] = settings.security[:signature_method]
7575
url_string = OneLogin::RubySaml::Utils.build_query(
7676
:type => 'SAMLRequest',
7777
:data => base64_request,
@@ -138,7 +138,7 @@ def create_xml_document(settings)
138138

139139
def sign_document(document, settings)
140140
# embed signature
141-
if settings.security[:logout_requests_signed] && settings.private_key && settings.certificate && settings.security[:embed_sign]
141+
if settings.idp_slo_service_binding == Utils::BINDINGS[:post] && settings.security[:logout_requests_signed] && settings.private_key && settings.certificate
142142
private_key = settings.get_sp_key
143143
cert = settings.get_sp_cert
144144
document.sign_document(private_key, cert, settings.security[:signature_method], settings.security[:digest_method])

0 commit comments

Comments
 (0)