From 981e4a34b5d5ea1c1e3da1518697e2cf5e6ab0b3 Mon Sep 17 00:00:00 2001 From: Andy Allan Date: Wed, 12 Dec 2018 13:58:38 +0100 Subject: [PATCH] Use only token capabilities when a token is provided The Authenticate#allow? method (from oauth-plugin) sets current_user as a side effect of checking the token. But this allows a valid token to access all actions that are available to that user, beyond the capabilities for that token. --- app/controllers/application_controller.rb | 4 +-- .../user_preferences_controller_test.rb | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 6c6a087b7..0411f75c4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -446,9 +446,9 @@ class ApplicationController < ActionController::Base end def current_ability - # Add in capabilities from the oauth token if it exists and is a valid access token + # Use capabilities from the oauth token if it exists and is a valid access token if Authenticator.new(self, [:token]).allow? - Ability.new(current_user).merge(Capability.new(current_token)) + Capability.new(current_token) else Ability.new(current_user) end diff --git a/test/controllers/user_preferences_controller_test.rb b/test/controllers/user_preferences_controller_test.rb index ddd7e2a40..99b40d5f0 100644 --- a/test/controllers/user_preferences_controller_test.rb +++ b/test/controllers/user_preferences_controller_test.rb @@ -210,4 +210,35 @@ class UserPreferencesControllerTest < ActionController::TestCase UserPreference.find([user.id, "key"]) end end + + # Ensure that a valid access token with correct capabilities can be used to + # read preferences + def test_read_one_using_token + user = create(:user) + token = create(:access_token, :user => user, :allow_read_prefs => true) + create(:user_preference, :user => user, :k => "key", :v => "value") + + # Hack together an oauth request - an alternative would be to sign the request properly + @request.env["oauth.version"] = 1 + @request.env["oauth.strategies"] = [:token] + @request.env["oauth.token"] = token + + get :read_one, :params => { :preference_key => "key" } + assert_response :success + end + + # Ensure that a valid access token with incorrect capabilities can't be used + # to read preferences even, though the owner of that token could read them + # by other methods. + def test_read_one_using_token_fail + user = create(:user) + token = create(:access_token, :user => user, :allow_read_prefs => false) + create(:user_preference, :user => user, :k => "key", :v => "value") + @request.env["oauth.version"] = 1 + @request.env["oauth.strategies"] = [:token] + @request.env["oauth.token"] = token + + get :read_one, :params => { :preference_key => "key" } + assert_response :forbidden + end end -- 2.43.2