Skip to content

Commit

Permalink
add allowed_service_uris config param
Browse files Browse the repository at this point in the history
  • Loading branch information
ccutrer committed Jul 25, 2017
1 parent 53c7fb3 commit e9bb151
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 4 deletions.
8 changes: 6 additions & 2 deletions config/config.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -534,10 +534,14 @@ log:
#downcase_username: true

# If you'd like to limit the service hosts that can use CAS for authentication,
# add the individual IPs and IP ranges in CIDR notation below. Leaving this
# setting blank will allow any server to authenticate users via the CAS server
# you can either limit specific service URIs (validating the service parameter),
# or add the individual IPs and IP ranges in CIDR notation below. Leaving these
# settings blank will allow any server to authenticate users via the CAS server
# and potentially harvest sensitive user information.

#allowed_service_uris:
# - https://myservice.com/login/cas

#allowed_service_ips:
# - 127.0.0.1
# - 192.168.0.0/24
19 changes: 18 additions & 1 deletion lib/casserver/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,11 @@ def self.init_database!

begin
if @service
if @renew
if !service_allowed?(@service)
$LOG.warn("Disallowed service '#{@service}'.")
@message = {:type => 'mistake',
:message => t.error.disallowed_service}
elsif @renew
$LOG.info("Authentication renew explicitly requested. Proceeding with CAS login for service #{@service.inspect}.")
elsif tgt && !tgt_error
$LOG.debug("Valid ticket granting ticket detected.")
Expand Down Expand Up @@ -409,6 +413,13 @@ def self.init_database!
@username.downcase!
end

if !@service.blank? && !service_allowed?(@service)
@message = {:type => 'mistake',
:message => t.error.disallowed_service}
status 400
return render @template_engine, :login
end

if error = validate_login_ticket(@lt)
@message = {:type => 'mistake', :message => error}
# generate another login ticket to allow for re-submitting the form
Expand Down Expand Up @@ -765,6 +776,12 @@ def compile_template(engine, data, options, views)
super engine, data, options, views
end

def service_allowed?(service)
allowed_uris = Array(settings.config[:allowed_service_uris])

allowed_uris.empty? || allowed_uris.include?(service)
end

def ip_allowed?(ip)
require 'ipaddr'

Expand Down
1 change: 1 addition & 0 deletions locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ error:
invalid_target_service: "The target service your browser supplied appears to be invalid. Please contact your system administrator for help."
unable_to_authenticate: "The client and server are unable to negotiate authentication. Please try logging in again later."
no_service_parameter_given: "The server cannot fulfill this gateway request because no service parameter was given."
disallowed_service: "The target service is not allowed to authenticate against this CAS server. Please contact your system administrator for help."

notice:
logged_in_as: "You are currently logged in as '%1'. If this is not you, please log in below."
Expand Down
44 changes: 44 additions & 0 deletions spec/casserver_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@
page.should have_content("You have successfully logged in")
end

it "auto-forwards when you're already logged in" do
visit "/login"

fill_in 'username', :with => VALID_USERNAME
fill_in 'password', :with => VALID_PASSWORD
click_button 'login-submit'

visit "/login?service="+CGI.escape(@target_service)

page.current_url.should =~ /^#{Regexp.escape(@target_service)}\/?\?ticket=ST\-[1-9rA-Z]+/
end

it "fails to log in with invalid password" do
visit "/login"
fill_in 'username', :with => VALID_USERNAME
Expand Down Expand Up @@ -92,6 +104,38 @@
#page.should have_xpath("<script>alert(32)</script>")
end

describe 'service_uri validation' do
let(:service) { 'http://imposter.com/' }

it "doesn't redirect back to untrusted services" do
visit "/login?service="+CGI.escape(service)

page.should have_content("The target service is not allowed")

fill_in 'username', :with => VALID_USERNAME
fill_in 'password', :with => VALID_PASSWORD

click_button 'login-submit'

page.should have_content("The target service is not allowed")
end

it "doesn't redirect back when already logged in" do
visit "/login"

fill_in 'username', :with => VALID_USERNAME
fill_in 'password', :with => VALID_PASSWORD

click_button 'login-submit'

visit "/login?service="+CGI.escape(service)

page.should have_content("The target service is not allowed")
end

end


end # describe '/login'


Expand Down
5 changes: 4 additions & 1 deletion spec/config/default_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ enable_single_sign_out: true
#downcase_username: true

allowed_service_ips:
- 127.0.0.0/24
- 127.0.0.0/24

allowed_service_uris:
- http://my.app.test

0 comments on commit e9bb151

Please sign in to comment.