Skip to content

Commit

Permalink
Discovers the SAML redirect and raises the appropriate error
Browse files Browse the repository at this point in the history
  • Loading branch information
Jared committed May 26, 2024
1 parent eb0c89b commit fb7e333
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
coverage
pkg
Gemfile.lock
.DS_Store
37 changes: 22 additions & 15 deletions app/controllers/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,26 @@ def check_target_availability
handle_redirection(res)
end

# def saml_authentication_required(res)
# return true
# end
def handle_scheme_change(effective_url, effective_uri)
# Case of http://a.com => https://a.com (or the opposite)
if !NS::ParsedCli.ignore_main_redirect && target.uri.domain == effective_uri.domain &&
target.uri.path == effective_uri.path && target.uri.scheme != effective_uri.scheme

target.url = effective_url
end
end

# Handle redirect if the target contains 'SAMLRequest', indicating a need for SAML authentication.
#
# @param [ Addressable::URI ] effective_uri
# @raise [ Error::SAMLAuthenticationRequired ] If the effective_uri contains 'SAMLRequest'
#
# @return [ Void ]
def handle_saml_authentication(effective_uri)
return false unless effective_uri

raise Error::SAMLAuthenticationRequired if effective_uri.to_s.match?(/[?&]SAMLRequest/i)
end

# Checks for redirects, an out of scope redirect will raise an Error::HTTPRedirect
#
Expand All @@ -62,18 +79,8 @@ def handle_redirection(res)
effective_url = target.homepage_res.effective_url # Basically get and follow location of target.url
effective_uri = Addressable::URI.parse(effective_url)

# if saml_authentication_required(res)
# # handle_saml_authentication(res)
# raise Error::SAMLAuthenticationRequired
# end

# Case of http://a.com => https://a.com (or the opposite)
if !NS::ParsedCli.ignore_main_redirect && target.uri.domain == effective_uri.domain &&
target.uri.path == effective_uri.path && target.uri.scheme != effective_uri.scheme

target.url = effective_url
end

handle_saml_authentication(effective_uri)
handle_scheme_change(effective_url, effective_uri)
return if target.in_scope?(effective_url)

raise Error::HTTPRedirect, effective_url unless NS::ParsedCli.ignore_main_redirect
Expand Down
1 change: 1 addition & 0 deletions lib/cms_scanner/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ class Standard < StandardError

require_relative 'errors/http'
require_relative 'errors/scan'
require_relative 'errors/saml'
2 changes: 1 addition & 1 deletion lib/cms_scanner/errors/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def initialize(url)
end

def to_s
"The URL blah blah blah supplied redirects to #{redirect_uri}. Use the --ignore-main-redirect "\
"The URL supplied redirects to #{redirect_uri}. Use the --ignore-main-redirect "\
'option to ignore the redirection and scan the target, or change the --url option ' \
'value to the redirected URL.'
end
Expand Down
4 changes: 3 additions & 1 deletion lib/cms_scanner/errors/saml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ module CMSScanner
module Error
# SAML Authentication Required Error
class SAMLAuthenticationRequired < Standard
# :nocov:
def to_s
'SAML authentication is required to access this resource.'\
'SAML authentication is required to access this resource. ' \
'Please ensure SAML authentication credentials are provided.'
end
# :nocov:
end
end
end
27 changes: 26 additions & 1 deletion spec/app/controllers/core_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@
it 'raises an error' do
expect { core.before_scan }.to raise_error(
CMSScanner::Error::HTTPRedirect,
"The URL blah blah blah supplied redirects to #{redirection}." \
"The URL supplied redirects to #{redirection}." \
' Use the --ignore-main-redirect option to ignore the redirection and scan the target,' \
' or change the --url option value to the redirected URL.'
)
Expand Down Expand Up @@ -346,4 +346,29 @@
core.after_scan
end
end

describe '#handle_redirection' do
let(:redirection) { 'http://example.com/?SAMLRequest=value' }
let(:response) { Typhoeus::Response.new(effective_url: redirection) }

before do
allow(core.target).to receive(:homepage_res).and_return(response)
allow(core.target).to receive(:in_scope?).with(redirection).and_return(true)
allow(Addressable::URI).to receive(:parse).with(redirection).and_return(Addressable::URI.parse(redirection))
end

context 'when redirection URL contains SAMLRequest' do
it 'raises SAMLAuthenticationRequired error' do
expect { core.handle_redirection(response) }.to raise_error(CMSScanner::Error::SAMLAuthenticationRequired)
end
end

context 'when redirection URL does not contain SAMLRequest' do
let(:redirection) { 'http://example.com/' } # No SAMLRequest in the URL

it 'does not raise any error' do
expect { core.handle_redirection(response) }.not_to raise_error
end
end
end
end

0 comments on commit fb7e333

Please sign in to comment.