Skip to content

Commit 3e31760

Browse files
Deprecate the settings.compress_request and settings.compress_response parameters. Set their behavior automatically based on settings.idp_sso_service_binding and settings.idp_slo_service_binding respectively. HTTP-Redirect will always use compression, while HTTP-POST will not. (#695)
1 parent e9c7f97 commit 3e31760

13 files changed

+88
-45
lines changed

.rubocop_todo.yml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This configuration was generated by
22
# `rubocop --auto-gen-config`
3-
# on 2024-07-09 11:29:15 UTC using RuboCop version 1.64.1.
3+
# on 2024-07-09 08:57:21 UTC using RuboCop version 1.64.1.
44
# The point is for the user to remove these configuration records
55
# one by one as the offenses are removed from the code base.
66
# Note that changes in the inspected code, or installation of new
@@ -294,7 +294,7 @@ Performance/StringReplacement:
294294
- 'lib/ruby_saml/utils.rb'
295295
- 'lib/ruby_saml/xml/document.rb'
296296

297-
# Offense count: 54
297+
# Offense count: 52
298298
# This cop supports safe autocorrection (--autocorrect).
299299
# Configuration parameters: EnforcedStyle.
300300
# SupportedStyles: separated, grouped
@@ -414,7 +414,15 @@ Style/ModuleFunction:
414414
Exclude:
415415
- 'lib/ruby_saml/logging.rb'
416416

417-
# Offense count: 15
417+
# Offense count: 1
418+
# This cop supports unsafe autocorrection (--autocorrect-all).
419+
# Configuration parameters: EnforcedStyle, Autocorrect.
420+
# SupportedStyles: module_function, extend_self, forbidden
421+
Style/ModuleFunction:
422+
Exclude:
423+
- 'lib/ruby_saml/logging.rb'
424+
425+
# Offense count: 16
418426
# Configuration parameters: AllowedMethods.
419427
# AllowedMethods: respond_to_missing?
420428
Style/OptionalBooleanParameter:

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* [#685](https://github.com/SAML-Toolkits/ruby-saml/pull/685) Move schema files from `lib/onelogin/schemas` to `lib/ruby_saml/schemas`.
88
* [#692](https://github.com/SAML-Toolkits/ruby-saml/pull/692) Remove `XMLSecurity` namespace and replace with `RubySaml::XML`.
99
* [#686](https://github.com/SAML-Toolkits/ruby-saml/pull/686) Use SHA-256 as the default hashing algorithm everywhere instead of SHA-1, including signatures, fingerprints, and digests.
10+
* [#695](https://github.com/SAML-Toolkits/ruby-saml/pull/695) Deprecate `settings.compress_request` and `settings.compess_response` parameters.
1011
* [#690](https://github.com/SAML-Toolkits/ruby-saml/pull/690) Remove deprecated `settings.security[:embed_sign]` parameter.
1112

1213
### 1.17.0

UPGRADING.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ settings.idp_slo_service_binding = :redirect
6868

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

71+
### Deprecation of Compression Settings
72+
73+
The `settings.compress_request` and `settings.compress_response` parameters have been deprecated
74+
and are no longer functional. They will be removed in RubySaml 2.1.0. Please remove `compress_request`
75+
and `compress_response` everywhere within your project code.
76+
77+
The SAML SP request/response message compression behavior is now controlled automatically by the
78+
`settings.idp_sso_service_binding` and `settings.idp_slo_service_binding` parameters respectively:
79+
`HTTP-Redirect` will always use compression, while `HTTP-POST` will not. For clarity, here
80+
"compression" is used to make redirect URLs which contain SAML messages be shorter. For POST messages,
81+
compression may be achieved by enabling `Content-Encoding: gzip` on your webserver.
82+
7183
## Updating from 1.12.x to 1.13.0
7284

7385
Version `1.13.0` adds `settings.idp_sso_service_binding` and `settings.idp_slo_service_binding`, and

lib/ruby_saml/authrequest.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def create_params(settings, params={})
5656
# The method expects :RelayState but sometimes we get 'RelayState' instead.
5757
# Based on the HashWithIndifferentAccess value in Rails we could experience
5858
# conflicts so this line will solve them.
59+
binding_redirect = settings.idp_sso_service_binding == Utils::BINDINGS[:redirect]
5960
relay_state = params[:RelayState] || params['RelayState']
6061

6162
if relay_state.nil?
@@ -71,12 +72,12 @@ def create_params(settings, params={})
7172

7273
Logging.debug "Created AuthnRequest: #{request}"
7374

74-
request = deflate(request) if settings.compress_request
75+
request = deflate(request) if binding_redirect
7576
base64_request = encode(request)
7677
request_params = {"SAMLRequest" => base64_request}
7778
sp_signing_key = settings.get_sp_signing_key
7879

79-
if settings.idp_sso_service_binding == Utils::BINDINGS[:redirect] && settings.security[:authn_requests_signed] && sp_signing_key
80+
if binding_redirect && settings.security[:authn_requests_signed] && sp_signing_key
8081
params['SigAlg'] = settings.security[:signature_method]
8182
url_string = RubySaml::Utils.build_query(
8283
type: 'SAMLRequest',

lib/ruby_saml/logoutrequest.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def create_params(settings, params={})
5353
# The method expects :RelayState but sometimes we get 'RelayState' instead.
5454
# Based on the HashWithIndifferentAccess value in Rails we could experience
5555
# conflicts so this line will solve them.
56+
binding_redirect = settings.idp_slo_service_binding == Utils::BINDINGS[:redirect]
5657
relay_state = params[:RelayState] || params['RelayState']
5758

5859
if relay_state.nil?
@@ -68,12 +69,12 @@ def create_params(settings, params={})
6869

6970
Logging.debug "Created SLO Logout Request: #{request}"
7071

71-
request = deflate(request) if settings.compress_request
72+
request = deflate(request) if binding_redirect
7273
base64_request = encode(request)
7374
request_params = {"SAMLRequest" => base64_request}
7475
sp_signing_key = settings.get_sp_signing_key
7576

76-
if settings.idp_slo_service_binding == Utils::BINDINGS[:redirect] && settings.security[:logout_requests_signed] && sp_signing_key
77+
if binding_redirect && settings.security[:logout_requests_signed] && sp_signing_key
7778
params['SigAlg'] = settings.security[:signature_method]
7879
url_string = RubySaml::Utils.build_query(
7980
type: 'SAMLRequest',

lib/ruby_saml/saml_message.rb

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
require 'rexml/document'
88
require 'rexml/xpath'
99
require 'ruby_saml/error_handling'
10+
require 'ruby_saml/logging'
1011

1112
# Only supports SAML 2.0
1213
module RubySaml
@@ -104,11 +105,18 @@ def decode_raw_saml(saml, settings = nil)
104105

105106
# Deflate, base64 encode and url-encode a SAML Message (To be used in the HTTP-redirect binding)
106107
# @param saml [String] The plain SAML Message
107-
# @param settings [RubySaml::Settings|nil] Toolkit settings
108+
# @param settings_or_compress [true|false|RubySaml::Settings|nil] Whether or not the SAML should be deflated.
109+
# The usage of RubySaml::Settings here is deprecated.
108110
# @return [String] The deflated and encoded SAML Message (encoded if the compression is requested)
109-
#
110-
def encode_raw_saml(saml, settings)
111-
saml = deflate(saml) if settings.compress_request
111+
def encode_raw_saml(saml, settings_or_compress = false)
112+
if settings_or_compress.is_a?(TrueClass)
113+
saml = deflate(saml)
114+
elsif settings_or_compress.respond_to?(:compress_request)
115+
Logging.deprecate('Please change the second argument of `encode_raw_saml_message` to a boolean ' \
116+
'indicating whether or not to use compression. Using a boolean will be required ' \
117+
'in RubySaml 2.1.0.')
118+
saml = deflate(saml) if settings_or_compress.compress_request
119+
end
112120

113121
CGI.escape(encode(saml))
114122
end

lib/ruby_saml/settings.rb

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ def initialize(overrides = {}, keep_security_attributes = false)
5252
attr_accessor :name_identifier_value
5353
attr_accessor :name_identifier_value_requested
5454
attr_accessor :sessionindex
55-
attr_accessor :compress_request
56-
attr_accessor :compress_response
5755
attr_accessor :double_quote_xml_attribute_values
5856
attr_accessor :message_max_bytesize
5957
attr_accessor :passive
@@ -274,8 +272,6 @@ def get_binding(value)
274272
assertion_consumer_service_binding: Utils::BINDINGS[:post],
275273
single_logout_service_binding: Utils::BINDINGS[:redirect],
276274
idp_cert_fingerprint_algorithm: RubySaml::XML::Document::SHA256,
277-
compress_request: true,
278-
compress_response: true,
279275
message_max_bytesize: 250_000,
280276
soft: true,
281277
double_quote_xml_attribute_values: false,
@@ -296,8 +292,40 @@ def get_binding(value)
296292
}.freeze
297293
}.freeze
298294

295+
# @deprecated Will be removed in v2.1.0
296+
def compress_request
297+
compress_deprecation('compress_request', 'idp_sso_service_binding')
298+
defined?(@compress_request) ? @compress_request : true
299+
end
300+
301+
# @deprecated Will be removed in v2.1.0
302+
def compress_request=(value)
303+
compress_deprecation('compress_request', 'idp_sso_service_binding')
304+
@compress_request = value
305+
end
306+
307+
# @deprecated Will be removed in v2.1.0
308+
def compress_response
309+
compress_deprecation('compress_response', 'idp_slo_service_binding')
310+
defined?(@compress_response) ? @compress_response : true
311+
end
312+
313+
# @deprecated Will be removed in v2.1.0
314+
def compress_response=(value)
315+
compress_deprecation('compress_response', 'idp_slo_service_binding')
316+
@compress_response = value
317+
end
318+
299319
private
300320

321+
# @deprecated Will be removed in v2.1.0
322+
def compress_deprecation(old_param, new_param)
323+
Logging.deprecate "`RubySaml::Settings##{old_param}` is deprecated and no longer functional. " \
324+
'It will be removed in RubySaml 2.1.0. ' \
325+
"Its functionality is now handled by `RubySaml::Settings##{new_param}` instead: " \
326+
'"HTTP-Redirect" will always be compressed, and "HTTP-POST" will always be uncompressed.'
327+
end
328+
301329
# @return [Hash<Symbol, Array<Array<OpenSSL::X509::Certificate, OpenSSL::PKey::RSA>>>]
302330
# Build the SP certificates and private keys from the settings. Returns all
303331
# certificates and private keys, even if they are expired.

lib/ruby_saml/slo_logoutresponse.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def create_params(settings, request_id = nil, logout_message = nil, params = {},
6262
# The method expects :RelayState but sometimes we get 'RelayState' instead.
6363
# Based on the HashWithIndifferentAccess value in Rails we could experience
6464
# conflicts so this line will solve them.
65+
binding_redirect = settings.idp_slo_service_binding == Utils::BINDINGS[:redirect]
6566
relay_state = params[:RelayState] || params['RelayState']
6667

6768
if relay_state.nil?
@@ -77,12 +78,12 @@ def create_params(settings, request_id = nil, logout_message = nil, params = {},
7778

7879
Logging.debug "Created SLO Logout Response: #{response}"
7980

80-
response = deflate(response) if settings.compress_response
81+
response = deflate(response) if binding_redirect
8182
base64_response = encode(response)
8283
response_params = {"SAMLResponse" => base64_response}
8384
sp_signing_key = settings.get_sp_signing_key
8485

85-
if settings.idp_slo_service_binding == Utils::BINDINGS[:redirect] && settings.security[:logout_responses_signed] && sp_signing_key
86+
if binding_redirect && settings.security[:logout_responses_signed] && sp_signing_key
8687
params['SigAlg'] = settings.security[:signature_method]
8788
url_string = RubySaml::Utils.build_query(
8889
type: 'SAMLResponse',

test/logoutrequest_test.rb

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -152,21 +152,7 @@ class RequestTest < Minitest::Test
152152
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmlenc#sha256'/>], inflated
153153
end
154154

155-
it "create a signed logout request" do
156-
settings.compress_request = true
157-
158-
unauth_req = RubySaml::Logoutrequest.new
159-
unauth_url = unauth_req.create(settings)
160-
161-
inflated = decode_saml_request_payload(unauth_url)
162-
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], inflated
163-
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'/>], inflated
164-
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmlenc#sha256'/>], inflated
165-
end
166-
167155
it "create an uncompressed signed logout request" do
168-
settings.compress_request = false
169-
170156
params = RubySaml::Logoutrequest.new.create_params(settings)
171157
request_xml = Base64.decode64(params["SAMLRequest"])
172158

@@ -176,7 +162,6 @@ class RequestTest < Minitest::Test
176162
end
177163

178164
it "create a signed logout request with 256 digest and signature method" do
179-
settings.compress_request = false
180165
settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256
181166
settings.security[:digest_method] = RubySaml::XML::Document::SHA256
182167

@@ -188,7 +173,6 @@ class RequestTest < Minitest::Test
188173
end
189174

190175
it "create a signed logout request with 512 digest and signature method RSA_SHA384" do
191-
settings.compress_request = false
192176
settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA384
193177
settings.security[:digest_method] = RubySaml::XML::Document::SHA512
194178

@@ -201,7 +185,6 @@ class RequestTest < Minitest::Test
201185
end
202186

203187
it "create a signed logout request using the first certificate and key" do
204-
settings.compress_request = false
205188
settings.certificate = nil
206189
settings.private_key = nil
207190
settings.sp_cert_multi = {
@@ -220,7 +203,6 @@ class RequestTest < Minitest::Test
220203
end
221204

222205
it "create a signed logout request using the first valid certificate and key when :check_sp_cert_expiration is true" do
223-
settings.compress_request = false
224206
settings.certificate = nil
225207
settings.private_key = nil
226208
settings.security[:check_sp_cert_expiration] = true
@@ -328,7 +310,6 @@ class RequestTest < Minitest::Test
328310

329311
it "create a signature parameter using the first certificate and key" do
330312
settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1
331-
settings.compress_request = false
332313
settings.certificate = nil
333314
settings.private_key = nil
334315
settings.sp_cert_multi = {

test/request_test.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class RequestTest < Minitest::Test
4242
end
4343

4444
it "create the SAMLRequest URL parameter without deflating" do
45-
settings.compress_request = false
45+
settings.idp_sso_service_binding = RubySaml::Utils::BINDINGS[:post]
4646
auth_url = RubySaml::Authrequest.new.create(settings)
4747
assert_match(/^http:\/\/example\.com\?SAMLRequest=/, auth_url)
4848
payload = CGI.unescape(auth_url.split("=").last)
@@ -242,7 +242,6 @@ class RequestTest < Minitest::Test
242242

243243
describe "#create_params signing with HTTP-POST binding" do
244244
before do
245-
settings.compress_request = false
246245
settings.idp_sso_service_url = "http://example.com?field=value"
247246
settings.idp_sso_service_binding = :post
248247
settings.security[:authn_requests_signed] = true
@@ -317,7 +316,6 @@ class RequestTest < Minitest::Test
317316
let(:cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) }
318317

319318
before do
320-
settings.compress_request = false
321319
settings.idp_sso_service_url = "http://example.com?field=value"
322320
settings.idp_sso_service_binding = :redirect
323321
settings.assertion_consumer_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"
@@ -362,7 +360,6 @@ class RequestTest < Minitest::Test
362360

363361
it "create a signature parameter using the first certificate and key" do
364362
settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1
365-
settings.compress_request = false
366363
settings.certificate = nil
367364
settings.private_key = nil
368365
settings.sp_cert_multi = {

0 commit comments

Comments
 (0)