Skip to content

Commit 533c84e

Browse files
committed
Minimize Zlib deflate decompression bomb. See #383
1 parent 2e2e9b2 commit 533c84e

2 files changed

Lines changed: 24 additions & 0 deletions

File tree

lib/onelogin/ruby-saml/saml_message.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class SamlMessage
2222
BASE64_FORMAT = %r(\A([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?\Z)
2323
@@mutex = Mutex.new
2424

25+
MAX_BYTE_SIZE = 250000
26+
2527
# @return [Nokogiri::XML::Schema] Gets the schema object of the SAML 2.0 Protocol schema
2628
#
2729
def self.schema
@@ -89,6 +91,10 @@ def valid_saml?(document, soft = true)
8991
def decode_raw_saml(saml)
9092
return saml unless base64_encoded?(saml)
9193

94+
if saml.bytesize > MAX_BYTE_SIZE
95+
raise ValidationError.new("Encoded SAML Message exceeds " + MAX_BYTE_SIZE.to_s + " bytes, so was rejected")
96+
end
97+
9298
decoded = decode(saml)
9399
begin
94100
inflate(decoded)

test/saml_message_test.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,23 @@ class RubySamlTest < Minitest::Test
5252
decoded_inflated = saml_message.send(:inflate, decoded)
5353
assert response_document_xml, decoded_inflated
5454
end
55+
56+
describe "Prevent Zlib bomb attack" do
57+
it "raises error when SAML Message exceed the allowed bytes" do
58+
prefix= """<?xml version='1.0' encoding='UTF-8'?>
59+
<samlp:LogoutRequest xmlns:samlp='urn:oasis:names:tc:SAML:2.0:protocol' xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion' ID='ONELOGIN_21df91a89767879fc0f7df6a1490c6000c81644d' Version='2.0' IssueInstant='2014-07-18T01:13:06Z' Destination='http://idp.example.com/SingleLogoutService.php'>
60+
<saml:Issuer>"""
61+
suffix= """</saml:Issuer>
62+
<saml:NameID SPNameQualifier='http://sp.example.com/demo1/metadata.php' Format='urn:oasis:names:tc:SAML:2.0:nameid-format:transient'>ONELOGIN_f92cc1834efc0f73e9c09f482fce80037a6251e7</saml:NameID>
63+
</samlp:LogoutRequest>"""
64+
65+
data = prefix + "A" * (200000 * 1024) + suffix
66+
bomb = Base64.encode64(Zlib::Deflate.deflate(data, 9)[2..-5])
67+
assert_raises(OneLogin::RubySaml::ValidationError, "Encoded SAML Message exceeds " + OneLogin::RubySaml::SamlMessage::MAX_BYTE_SIZE.to_s + " bytes, so was rejected") do
68+
saml_message = OneLogin::RubySaml::SamlMessage.new
69+
saml_message.send(:decode_raw_saml, bomb)
70+
end
71+
end
72+
end
5573
end
5674
end

0 commit comments

Comments
 (0)