ruby-saml 1.13.0 → 1.14.0
Sign up to get free protection for your applications and to get access to all the features.
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
|