ruby-saml 1.13.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ruby-saml might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.github/workflows/test.yml +1 -1
- data/CHANGELOG.md +5 -0
- data/README.md +31 -2
- data/UPGRADING.md +1 -1
- data/lib/onelogin/ruby-saml/authrequest.rb +1 -1
- data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +1 -1
- data/lib/onelogin/ruby-saml/logoutrequest.rb +1 -1
- data/lib/onelogin/ruby-saml/logoutresponse.rb +1 -1
- data/lib/onelogin/ruby-saml/response.rb +6 -1
- data/lib/onelogin/ruby-saml/settings.rb +3 -1
- data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +1 -26
- data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +1 -1
- data/lib/onelogin/ruby-saml/utils.rb +20 -6
- data/lib/onelogin/ruby-saml/version.rb +1 -1
- data/ruby-saml.gemspec +7 -2
- metadata +7 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 045af020626d4568d7d509d0c076f826de5cd57a729816676bd1624980714000
|
4
|
+
data.tar.gz: 74c3609fc7882d772aca5dc47b8baa7edbdae0ecdcfb9ca9502ad0b743b7ac8e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eddf856fb0e603d48046306999ad9f0574dfc5155068e047cb0eba3e2a2afbdc120a55ca975382d48093d39be54427ff4e961cacdca7e6fc4b5ab62bfd69c657
|
7
|
+
data.tar.gz: e0b5449786268ea5a058f607d7ad44c6c96856a99c4e027b7c9db7671ebda83e9304c1438b49b030cc3030af3d24d33b0f242ce06ca4963a5a42e95e441982c2
|
data/.github/workflows/test.yml
CHANGED
@@ -9,7 +9,7 @@ jobs:
|
|
9
9
|
fail-fast: false
|
10
10
|
matrix:
|
11
11
|
os: [ubuntu-latest, macos-latest]
|
12
|
-
ruby-version: [2.1.9, 2.2.10, 2.3.8, 2.4.6, 2.5.8, 2.6.6, 2.7.2, 3.0.1, jruby-9.1.17.0, jruby-9.2.17.0, truffleruby]
|
12
|
+
ruby-version: [2.1.9, 2.2.10, 2.3.8, 2.4.6, 2.5.8, 2.6.6, 2.7.2, 3.0.1, '3.1', jruby-9.1.17.0, jruby-9.2.17.0, truffleruby]
|
13
13
|
runs-on: ${{ matrix.os }}
|
14
14
|
steps:
|
15
15
|
- uses: actions/checkout@v2
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,9 @@
|
|
1
1
|
# Ruby SAML Changelog
|
2
|
+
### 1.14.0 (Feb 01, 2022)
|
3
|
+
* [#627](https://github.com/onelogin/ruby-saml/pull/627) Support escape downcasing for validating SLO Signatures of ADFS/Azure
|
4
|
+
* [#633](https://github.com/onelogin/ruby-saml/pull/633) Support ability to change ID prefix
|
5
|
+
* Make the uuid editable on the SAML Messages generated by the toolkit
|
6
|
+
* [#622](https://github.com/onelogin/ruby-saml/pull/622) Add security setting to more strictly enforce audience validation
|
2
7
|
|
3
8
|
### 1.13.0 (Sept 06, 2021)
|
4
9
|
* [#611](https://github.com/onelogin/ruby-saml/pull/601) Replace MAX_BYTE_SIZE constant with setting: message_max_bytesize
|
data/README.md
CHANGED
@@ -66,7 +66,7 @@ However, ruby-saml never enables this dangerous Nokogiri configuration;
|
|
66
66
|
ruby-saml never enables DTDLOAD, and it never disables NONET.
|
67
67
|
|
68
68
|
The OneLogin::RubySaml::IdpMetadataParser class does not validate in any way the URL
|
69
|
-
that is introduced in order to be parsed.
|
69
|
+
that is introduced in order to be parsed.
|
70
70
|
|
71
71
|
Usually the same administrator that handles the Service Provider also sets the URL to
|
72
72
|
the IdP, which should be a trusted resource.
|
@@ -664,6 +664,29 @@ validation fails. You may disable such exceptions using the `settings.security[:
|
|
664
664
|
settings.security[:soft] = true # Do not raise error on failed signature/certificate validations
|
665
665
|
```
|
666
666
|
|
667
|
+
#### Audience Validation
|
668
|
+
|
669
|
+
A service provider should only consider a SAML response valid if the IdP includes an <AudienceRestriction>
|
670
|
+
element containting an <Audience> element that uniquely identifies the service provider. Unless you specify
|
671
|
+
the `skip_audience` option, Ruby SAML will validate that each SAML response includes an <Audience> element
|
672
|
+
whose contents matches `settings.sp_entity_id`.
|
673
|
+
|
674
|
+
By default, Ruby SAML considers an <AudienceRestriction> element containing only empty <Audience> elements
|
675
|
+
to be valid. That means an otherwise valid SAML response with a condition like this would be valid:
|
676
|
+
|
677
|
+
```xml
|
678
|
+
<AudienceRestriction>
|
679
|
+
<Audience />
|
680
|
+
</AudienceRestriction>
|
681
|
+
```
|
682
|
+
|
683
|
+
You may enforce that an <AudienceRestriction> element containing only empty <Audience> elements
|
684
|
+
is invalid using the `settings.security[:strict_audience_validation]` parameter.
|
685
|
+
|
686
|
+
```ruby
|
687
|
+
settings.security[:strict_audience_validation] = true
|
688
|
+
```
|
689
|
+
|
667
690
|
#### Key Rollover
|
668
691
|
|
669
692
|
To update the SP X.509 certificate and private key without disruption of service, you may define the parameter
|
@@ -767,7 +790,13 @@ Here is an example that we could add to our previous controller to process a SAM
|
|
767
790
|
# Method to handle IdP initiated logouts
|
768
791
|
def idp_logout_request
|
769
792
|
settings = Account.get_saml_settings
|
770
|
-
|
793
|
+
# ADFS URL-Encodes SAML data as lowercase, and the toolkit by default uses
|
794
|
+
# uppercase. Turn it True for ADFS compatibility on signature verification
|
795
|
+
settings.security[:lowercase_url_encoding] = true
|
796
|
+
|
797
|
+
logout_request = OneLogin::RubySaml::SloLogoutrequest.new(
|
798
|
+
params[:SAMLRequest], settings: settings
|
799
|
+
)
|
771
800
|
if !logout_request.is_valid?
|
772
801
|
logger.error "IdP initiated LogoutRequest was not valid!"
|
773
802
|
return render :inline => logger.error
|
data/UPGRADING.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Ruby SAML Migration Guide
|
2
2
|
|
3
|
-
## Updating from 1.12.x to 1.13.0
|
3
|
+
## Updating from 1.12.x to 1.13.0
|
4
4
|
|
5
5
|
Version `1.13.0` adds `settings.idp_sso_service_binding` and `settings.idp_slo_service_binding`, and
|
6
6
|
deprecates `settings.security[:embed_sign]`. If specified, new binding parameters will be used in place of `:embed_sign`
|
@@ -442,7 +442,7 @@ module OneLogin
|
|
442
442
|
priority = Array(priority)
|
443
443
|
if priority.any?
|
444
444
|
values = nodes.map(&:text)
|
445
|
-
|
445
|
+
priority.detect { |candidate| values.include?(candidate) }
|
446
446
|
else
|
447
447
|
nodes.first.text
|
448
448
|
end
|
@@ -12,7 +12,7 @@ module OneLogin
|
|
12
12
|
class Logoutrequest < SamlMessage
|
13
13
|
|
14
14
|
# Logout Request ID
|
15
|
-
|
15
|
+
attr_accessor :uuid
|
16
16
|
|
17
17
|
# Initializes the Logout Request. A Logoutrequest Object that is an extension of the SamlMessage class.
|
18
18
|
# Asigns an ID, a random uuid.
|
@@ -212,7 +212,7 @@ module OneLogin
|
|
212
212
|
return true unless options.has_key? :get_params
|
213
213
|
return true unless options[:get_params].has_key? 'Signature'
|
214
214
|
|
215
|
-
options[:raw_get_params] = OneLogin::RubySaml::Utils.prepare_raw_get_params(options[:raw_get_params], options[:get_params])
|
215
|
+
options[:raw_get_params] = OneLogin::RubySaml::Utils.prepare_raw_get_params(options[:raw_get_params], options[:get_params], settings.security[:lowercase_url_encoding])
|
216
216
|
|
217
217
|
if options[:get_params]['SigAlg'].nil? && !options[:raw_get_params]['SigAlg'].nil?
|
218
218
|
options[:get_params]['SigAlg'] = CGI.unescape(options[:raw_get_params]['SigAlg'])
|
@@ -613,7 +613,12 @@ module OneLogin
|
|
613
613
|
#
|
614
614
|
def validate_audience
|
615
615
|
return true if options[:skip_audience]
|
616
|
-
return true if
|
616
|
+
return true if settings.sp_entity_id.nil? || settings.sp_entity_id.empty?
|
617
|
+
|
618
|
+
if audiences.empty?
|
619
|
+
return true unless settings.security[:strict_audience_validation]
|
620
|
+
return append_error("Invalid Audiences. The <AudienceRestriction> element contained only empty <Audience> elements. Expected audience #{settings.sp_entity_id}.")
|
621
|
+
end
|
617
622
|
|
618
623
|
unless audiences.include? settings.sp_entity_id
|
619
624
|
s = audiences.count > 1 ? 's' : '';
|
@@ -280,7 +280,9 @@ module OneLogin
|
|
280
280
|
:digest_method => XMLSecurity::Document::SHA1,
|
281
281
|
:signature_method => XMLSecurity::Document::RSA_SHA1,
|
282
282
|
:check_idp_cert_expiration => false,
|
283
|
-
:check_sp_cert_expiration => false
|
283
|
+
:check_sp_cert_expiration => false,
|
284
|
+
:strict_audience_validation => false,
|
285
|
+
:lowercase_url_encoding => false
|
284
286
|
}.freeze
|
285
287
|
}.freeze
|
286
288
|
end
|
@@ -248,32 +248,8 @@ module OneLogin
|
|
248
248
|
return true unless options.has_key? :get_params
|
249
249
|
return true unless options[:get_params].has_key? 'Signature'
|
250
250
|
|
251
|
-
|
252
|
-
# of URI-encoded values _as sent by the IDP_:
|
253
|
-
#
|
254
|
-
# > Further, note that URL-encoding is not canonical; that is, there are multiple legal encodings for a given
|
255
|
-
# > value. The relying party MUST therefore perform the verification step using the original URL-encoded
|
256
|
-
# > values it received on the query string. It is not sufficient to re-encode the parameters after they have been
|
257
|
-
# > processed by software because the resulting encoding may not match the signer's encoding.
|
258
|
-
#
|
259
|
-
# <http://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf>
|
260
|
-
#
|
261
|
-
# If we don't have the original parts (for backward compatibility) required to correctly verify the signature,
|
262
|
-
# then fabricate them by re-encoding the parsed URI parameters, and hope that we're lucky enough to use
|
263
|
-
# the exact same URI-encoding as the IDP. (This is not the case if the IDP is ADFS!)
|
264
|
-
options[:raw_get_params] ||= {}
|
265
|
-
if options[:raw_get_params]['SAMLRequest'].nil? && !options[:get_params]['SAMLRequest'].nil?
|
266
|
-
options[:raw_get_params]['SAMLRequest'] = CGI.escape(options[:get_params]['SAMLRequest'])
|
267
|
-
end
|
268
|
-
if options[:raw_get_params]['RelayState'].nil? && !options[:get_params]['RelayState'].nil?
|
269
|
-
options[:raw_get_params]['RelayState'] = CGI.escape(options[:get_params]['RelayState'])
|
270
|
-
end
|
271
|
-
if options[:raw_get_params]['SigAlg'].nil? && !options[:get_params]['SigAlg'].nil?
|
272
|
-
options[:raw_get_params]['SigAlg'] = CGI.escape(options[:get_params]['SigAlg'])
|
273
|
-
end
|
251
|
+
options[:raw_get_params] = OneLogin::RubySaml::Utils.prepare_raw_get_params(options[:raw_get_params], options[:get_params], settings.security[:lowercase_url_encoding])
|
274
252
|
|
275
|
-
# If we only received the raw version of SigAlg,
|
276
|
-
# then parse it back into the decoded params hash for convenience.
|
277
253
|
if options[:get_params]['SigAlg'].nil? && !options[:raw_get_params]['SigAlg'].nil?
|
278
254
|
options[:get_params]['SigAlg'] = CGI.unescape(options[:raw_get_params]['SigAlg'])
|
279
255
|
end
|
@@ -335,7 +311,6 @@ module OneLogin
|
|
335
311
|
|
336
312
|
true
|
337
313
|
end
|
338
|
-
|
339
314
|
end
|
340
315
|
end
|
341
316
|
end
|
@@ -13,7 +13,7 @@ module OneLogin
|
|
13
13
|
class SloLogoutresponse < SamlMessage
|
14
14
|
|
15
15
|
# Logout Response ID
|
16
|
-
|
16
|
+
attr_accessor :uuid
|
17
17
|
|
18
18
|
# Initializes the Logout Response. A SloLogoutresponse Object that is an extension of the SamlMessage class.
|
19
19
|
# Asigns an ID, a random uuid.
|
@@ -32,6 +32,7 @@ module OneLogin
|
|
32
32
|
(\d+)W # 8: Weeks
|
33
33
|
)
|
34
34
|
$)x.freeze
|
35
|
+
UUID_PREFIX = '_'
|
35
36
|
|
36
37
|
# Checks if the x509 cert provided is expired
|
37
38
|
#
|
@@ -166,27 +167,36 @@ module OneLogin
|
|
166
167
|
#
|
167
168
|
# @param rawparams [Hash] Raw GET Parameters
|
168
169
|
# @param params [Hash] GET Parameters
|
170
|
+
# @param lowercase_url_encoding [bool] Lowercase URL Encoding (For ADFS urlencode compatiblity)
|
169
171
|
# @return [Hash] New raw parameters
|
170
172
|
#
|
171
|
-
def self.prepare_raw_get_params(rawparams, params)
|
173
|
+
def self.prepare_raw_get_params(rawparams, params, lowercase_url_encoding=false)
|
172
174
|
rawparams ||= {}
|
173
175
|
|
174
176
|
if rawparams['SAMLRequest'].nil? && !params['SAMLRequest'].nil?
|
175
|
-
rawparams['SAMLRequest'] =
|
177
|
+
rawparams['SAMLRequest'] = escape_request_param(params['SAMLRequest'], lowercase_url_encoding)
|
176
178
|
end
|
177
179
|
if rawparams['SAMLResponse'].nil? && !params['SAMLResponse'].nil?
|
178
|
-
rawparams['SAMLResponse'] =
|
180
|
+
rawparams['SAMLResponse'] = escape_request_param(params['SAMLResponse'], lowercase_url_encoding)
|
179
181
|
end
|
180
182
|
if rawparams['RelayState'].nil? && !params['RelayState'].nil?
|
181
|
-
rawparams['RelayState'] =
|
183
|
+
rawparams['RelayState'] = escape_request_param(params['RelayState'], lowercase_url_encoding)
|
182
184
|
end
|
183
185
|
if rawparams['SigAlg'].nil? && !params['SigAlg'].nil?
|
184
|
-
rawparams['SigAlg'] =
|
186
|
+
rawparams['SigAlg'] = escape_request_param(params['SigAlg'], lowercase_url_encoding)
|
185
187
|
end
|
186
188
|
|
187
189
|
rawparams
|
188
190
|
end
|
189
191
|
|
192
|
+
def self.escape_request_param(param, lowercase_url_encoding)
|
193
|
+
CGI.escape(param).tap do |escaped|
|
194
|
+
next unless lowercase_url_encoding
|
195
|
+
|
196
|
+
escaped.gsub!(/%[A-Fa-f0-9]{2}/) { |match| match.downcase }
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
190
200
|
# Validate the Signature parameter sent on the HTTP-Redirect binding
|
191
201
|
# @param params [Hash] Parameters to be used in the validation process
|
192
202
|
# @option params [OpenSSL::X509::Certificate] cert The Identity provider public certtificate
|
@@ -333,8 +343,12 @@ module OneLogin
|
|
333
343
|
end
|
334
344
|
end
|
335
345
|
|
346
|
+
def self.set_prefix(value)
|
347
|
+
UUID_PREFIX.replace value
|
348
|
+
end
|
349
|
+
|
336
350
|
def self.uuid
|
337
|
-
RUBY_VERSION < '1.9' ? "
|
351
|
+
"#{UUID_PREFIX}" + (RUBY_VERSION < '1.9' ? "#{@@uuid_generator.generate}" : "#{SecureRandom.uuid}")
|
338
352
|
end
|
339
353
|
|
340
354
|
# Given two strings, attempt to match them as URIs using Rails' parse method. If they can be parsed,
|
data/ruby-saml.gemspec
CHANGED
@@ -41,7 +41,7 @@ Gem::Specification.new do |s|
|
|
41
41
|
s.add_runtime_dependency('nokogiri', '>= 1.5.10', '<= 1.6.8.1')
|
42
42
|
s.add_runtime_dependency('json', '< 2.3.0')
|
43
43
|
elsif RUBY_VERSION < '2.3'
|
44
|
-
s.add_runtime_dependency('nokogiri', '>= 1.9.1', '
|
44
|
+
s.add_runtime_dependency('nokogiri', '>= 1.9.1', '< 1.10.0')
|
45
45
|
else
|
46
46
|
s.add_runtime_dependency('nokogiri', '>= 1.10.5')
|
47
47
|
s.add_runtime_dependency('rexml')
|
@@ -54,7 +54,12 @@ Gem::Specification.new do |s|
|
|
54
54
|
s.add_development_dependency('shoulda', '~> 2.11')
|
55
55
|
s.add_development_dependency('simplecov')
|
56
56
|
s.add_development_dependency('systemu', '~> 2')
|
57
|
-
|
57
|
+
|
58
|
+
if RUBY_VERSION < '2.1'
|
59
|
+
s.add_development_dependency('timecop', '<= 0.6.0')
|
60
|
+
else
|
61
|
+
s.add_development_dependency('timecop', '~> 0.9')
|
62
|
+
end
|
58
63
|
|
59
64
|
if defined?(JRUBY_VERSION)
|
60
65
|
# All recent versions of JRuby play well with pry
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-saml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OneLogin LLC
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -140,16 +140,16 @@ dependencies:
|
|
140
140
|
name: timecop
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- - "
|
143
|
+
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 0.
|
145
|
+
version: '0.9'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 0.
|
152
|
+
version: '0.9'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: pry-byebug
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -237,8 +237,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
237
237
|
- !ruby/object:Gem::Version
|
238
238
|
version: '0'
|
239
239
|
requirements: []
|
240
|
-
|
241
|
-
rubygems_version: 2.5.2.1
|
240
|
+
rubygems_version: 3.0.6
|
242
241
|
signing_key:
|
243
242
|
specification_version: 4
|
244
243
|
summary: SAML Ruby Tookit
|