Skip to content

Commit 4564638

Browse files
committed
Merge pull request #183 from onelogin/AUTH-255
AUTH-255: Sanitize document.signed_element_id via a prepared statement Conflicts: Gemfile test/response_test.rb
1 parent 84c3a6f commit 4564638

File tree

5 files changed

+49
-13
lines changed

5 files changed

+49
-13
lines changed

Gemfile

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
1+
#
2+
# Please keep this file alphabetized and organized
3+
#
14
source 'http://rubygems.org'
25

36
gemspec
47

58
group :test do
6-
gem "ruby-debug", "~> 0.10.4", :require => nil, :platforms => :ruby_18
7-
gem "debugger", "~> 1.1", :require => nil, :platforms => :ruby_19
8-
gem "shoulda", "~> 2.11"
9-
gem "rake", "~> 10"
10-
gem "mocha", "~> 0.14"
11-
gem "nokogiri", "~> 1.5.0"
12-
gem "timecop", "<= 0.6.0"
13-
gem "systemu", "~> 2"
14-
gem "rspec", "~> 2"
9+
if RUBY_VERSION < '1.9'
10+
gem 'nokogiri', '~> 1.5.0'
11+
gem 'ruby-debug', '~> 0.10.4'
12+
elsif RUBY_VERSION < '2.0'
13+
gem 'debugger-linecache', '~> 1.2.0'
14+
gem 'debugger', '~> 1.6.4'
15+
elsif RUBY_VERSION < '2.1'
16+
gem 'byebug', '~> 2.1.1'
17+
else
18+
gem 'pry-byebug'
19+
end
20+
21+
gem 'mocha', '~> 0.14', :require => false
22+
gem 'rake', '~> 10'
23+
gem 'shoulda', '~> 2.11'
24+
gem 'systemu', '~> 2'
25+
gem 'test-unit', '~> 3'
26+
gem 'timecop', '<= 0.6.0'
1527
end

lib/onelogin/ruby-saml/response.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,18 @@ def validate_response_state(soft = true)
151151
end
152152

153153
def xpath_first_from_signed_assertion(subelt=nil)
154-
node = REXML::XPath.first(document, "/p:Response/a:Assertion[@ID='#{document.signed_element_id}']#{subelt}", { "p" => PROTOCOL, "a" => ASSERTION })
155-
node ||= REXML::XPath.first(document, "/p:Response[@ID='#{document.signed_element_id}']/a:Assertion#{subelt}", { "p" => PROTOCOL, "a" => ASSERTION })
154+
node = REXML::XPath.first(
155+
document,
156+
"/p:Response/a:Assertion[@ID=$id]#{subelt}",
157+
{ "p" => PROTOCOL, "a" => ASSERTION },
158+
{ 'id' => document.signed_element_id }
159+
)
160+
node ||= REXML::XPath.first(
161+
document,
162+
"/p:Response[@ID=$id]/a:Assertion#{subelt}",
163+
{ "p" => PROTOCOL, "a" => ASSERTION },
164+
{ 'id' => document.signed_element_id }
165+
)
156166
node
157167
end
158168

test/response_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,5 +254,13 @@ class RubySamlTest < Test::Unit::TestCase
254254
end
255255
end
256256

257+
context '#xpath_first_from_signed_assertion' do
258+
should 'not allow arbitrary code execution' do
259+
malicious_response_document = fixture('response_eval', false)
260+
response = OneLogin::RubySaml::Response.new(malicious_response_document)
261+
response.send(:xpath_first_from_signed_assertion)
262+
assert_equal($evalled, nil)
263+
end
264+
end
257265
end
258266
end

test/responses/response_eval.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<saml:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:protocol">
2+
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
3+
<ds:SignedInfo>
4+
<ds:Reference URI="#x'] or eval('$evalled = true') or /[@ID='v"/>
5+
</ds:SignedInfo>
6+
</ds:Signature>
7+
</saml:Response>

test/test_helper.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
require 'rubygems'
22
require 'test/unit'
33
require 'shoulda'
4-
require 'ruby-debug'
54
require 'mocha/setup'
65
require 'timecop'
76

@@ -63,7 +62,7 @@ def wrapped_response_2
6362
def signature_fingerprint_1
6463
@signature_fingerprint1 ||= "C5:19:85:D9:47:F1:BE:57:08:20:25:05:08:46:EB:27:F6:CA:B7:83"
6564
end
66-
65+
6766
def signature_1
6867
@signature1 ||= File.read(File.join(File.dirname(__FILE__), 'certificates', 'certificate1'))
6968
end

0 commit comments

Comments
 (0)