Merge pull request #790 from ZogStriP/fix-security-bug-XHR-check-bypass

FIX: [security bug] XHR check bypass
This commit is contained in:
Sam 2013-04-29 19:31:52 -07:00
commit bb82d44ccc
2 changed files with 14 additions and 16 deletions

View File

@ -38,7 +38,6 @@ class ApplicationController < ActionController::Base
# Some exceptions # Some exceptions
class RenderEmpty < Exception; end class RenderEmpty < Exception; end
class NotLoggedIn < Exception; end
# Render nothing unless we are an xhr request # Render nothing unless we are an xhr request
rescue_from RenderEmpty do rescue_from RenderEmpty do
@ -246,10 +245,7 @@ class ApplicationController < ActionController::Base
def check_xhr def check_xhr
unless (controller_name == 'forums' || controller_name == 'user_open_ids') unless (controller_name == 'forums' || controller_name == 'user_open_ids')
# bypass xhr check on PUT / POST / DELETE provided api key is there, otherwise calling api is annoying # bypass xhr check on PUT / POST / DELETE provided api key is there, otherwise calling api is annoying
if !request.get? && request["api_key"] return if !request.get? && request["api_key"] && SiteSetting.api_key_valid?(request["api_key"])
return
end
raise RenderEmpty.new unless ((request.format && request.format.json?) || request.xhr?) raise RenderEmpty.new unless ((request.format && request.format.json?) || request.xhr?)
end end
end end

View File

@ -1,7 +1,7 @@
require 'spec_helper' require 'spec_helper'
describe 'api' do describe 'api' do
before do before do
fake_key = SecureRandom.hex(32) fake_key = SecureRandom.hex(32)
SiteSetting.stubs(:api_key).returns(fake_key) SiteSetting.stubs(:api_key).returns(fake_key)
end end
@ -11,26 +11,28 @@ describe 'api' do
Fabricate(:user) Fabricate(:user)
end end
let(:post) do let(:post) do
Fabricate(:post) Fabricate(:post)
end end
# choosing an arbitrarily easy to mock trusted activity # choosing an arbitrarily easy to mock trusted activity
it 'allows users with api key to bookmark posts' do it 'allows users with api key to bookmark posts' do
PostAction.expects(:act).with(user,post,PostActionType.types[:bookmark]).returns(true) PostAction.expects(:act).with(user, post, PostActionType.types[:bookmark]).once
put :bookmark, bookmarked: "true" ,post_id: post.id , api_key: SiteSetting.api_key, api_username: user.username put :bookmark, bookmarked: "true", post_id: post.id, api_key: SiteSetting.api_key, api_username: user.username, format: :json
end end
it 'disallows phonies to bookmark posts' do it 'disallows phonies to bookmark posts' do
lambda do PostAction.expects(:act).with(user, post, PostActionType.types[:bookmark]).never
put :bookmark, bookmarked: "true" ,post_id: post.id , api_key: SecureRandom.hex(32), api_username: user.username lambda do
put :bookmark, bookmarked: "true", post_id: post.id, api_key: SecureRandom.hex(32), api_username: user.username, format: :json
end.should raise_error Discourse::NotLoggedIn end.should raise_error Discourse::NotLoggedIn
end end
it 'disallows blank api' do it 'disallows blank api' do
SiteSetting.stubs(:api_key).returns("") SiteSetting.stubs(:api_key).returns("")
lambda do PostAction.expects(:act).with(user, post, PostActionType.types[:bookmark]).never
put :bookmark, bookmarked: "true" ,post_id: post.id , api_key: "", api_username: user.username lambda do
put :bookmark, bookmarked: "true", post_id: post.id, api_key: "", api_username: user.username, format: :json
end.should raise_error Discourse::NotLoggedIn end.should raise_error Discourse::NotLoggedIn
end end
end end