Skip to content

Commit 70e6544

Browse files
authored
Merge branch 'master' into force-escape-downcasing
2 parents b6b4de7 + 74c2545 commit 70e6544

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,29 @@ validation fails. You may disable such exceptions using the `settings.security[:
664664
settings.security[:soft] = true # Do not raise error on failed signature/certificate validations
665665
```
666666
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+
667690
#### Key Rollover
668691
669692
To update the SP X.509 certificate and private key without disruption of service, you may define the parameter

lib/onelogin/ruby-saml/response.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,12 @@ def validate_in_response_to
613613
#
614614
def validate_audience
615615
return true if options[:skip_audience]
616-
return true if audiences.empty? || settings.sp_entity_id.nil? || settings.sp_entity_id.empty?
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
617622

618623
unless audiences.include? settings.sp_entity_id
619624
s = audiences.count > 1 ? 's' : '';

lib/onelogin/ruby-saml/settings.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ def get_binding(value)
281281
:signature_method => XMLSecurity::Document::RSA_SHA1,
282282
:check_idp_cert_expiration => false,
283283
:check_sp_cert_expiration => false,
284+
:strict_audience_validation => false,
284285
:lowercase_url_encoding => false
285286
}.freeze
286287
}.freeze

test/response_test.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,14 +490,22 @@ def generate_audience_error(expected, actual)
490490
assert_empty response.errors
491491
end
492492

493-
it "return true when the audience is self closing" do
493+
it "return true when the audience is self closing and strict audience validation is not enabled" do
494494
response_audience_self_closed.settings = settings
495495
response_audience_self_closed.settings.sp_entity_id = '{audience}'
496496
assert response_audience_self_closed.send(:validate_audience)
497497
assert_empty response_audience_self_closed.errors
498498
end
499499

500-
it "return false when the audience is valid" do
500+
it "return false when the audience is self closing and strict audience validation is enabled" do
501+
response_audience_self_closed.settings = settings
502+
response_audience_self_closed.settings.security[:strict_audience_validation] = true
503+
response_audience_self_closed.settings.sp_entity_id = '{audience}'
504+
refute response_audience_self_closed.send(:validate_audience)
505+
assert_includes response_audience_self_closed.errors, "Invalid Audiences. The <AudienceRestriction> element contained only empty <Audience> elements. Expected audience {audience}."
506+
end
507+
508+
it "return false when the audience is invalid" do
501509
response.settings = settings
502510
response.settings.sp_entity_id = 'invalid_audience'
503511
assert !response.send(:validate_audience)

0 commit comments

Comments
 (0)