v3: implement query params whitelisting to avoid argument injection attacks

This commit is contained in:
Konstantin Haase 2015-04-13 16:00:47 +02:00
parent 5efdcc24c8
commit 51c2d1f0bf
6 changed files with 42 additions and 28 deletions

View File

@ -17,7 +17,7 @@ module Travis::API::V3
raise NotFound unless factory
service = factory.new(access_control, env_params.merge(params))
service = factory.new(access_control, factory.filter_params(env_params).merge(params))
result = service.run
render(result, env_params, env)
rescue Error => error

View File

@ -1,5 +1,8 @@
module Travis::API::V3
class Service
DEFAULT_PARAMS = [ "include".freeze, "@type".freeze ]
private_constant :DEFAULT_PARAMS
def self.result_type(type = nil)
@result_type = type if type
@result_type ||= parent.result_type if parent and parent.respond_to? :result_type
@ -7,6 +10,20 @@ module Travis::API::V3
@result_type
end
def self.filter_params(params)
wanted = self.params
params.select { |key| wanted.include? key }
end
def self.params(*list, prefix: nil)
@params ||= superclass.respond_to?(:params) ? superclass.params.dup : DEFAULT_PARAMS
list.each do |entry|
@params << entry.to_s
@params << "#{prefix || result_type}.#{entry}" if entry.is_a? Symbol
end
@params
end
attr_accessor :access_control, :params
def initialize(access_control, params)

View File

@ -1,5 +1,5 @@
module Travis::API::V3
class Services::Repositories::ForCurrentUser < Service
class Services::Organizations::ForCurrentUser < Service
def run!
raise LoginRequired unless access_control.logged_in?
query.for_member(access_control.user)

View File

@ -1,5 +1,7 @@
module Travis::API::V3
class Services::Organizations::ForCurrentUser < Service
class Services::Repositories::ForCurrentUser < Service
params :active, :private, prefix: :repository
def run!
raise LoginRequired unless access_control.logged_in?
query.for_member(access_control.user)

View File

@ -5,6 +5,7 @@ module Travis::API::V3
private_constant :TIME_FRAME, :LIMIT
result_type :request
params "request", "user", :config, :message, :branch
def run
raise LoginRequired unless access_control.logged_in? or access_control.full_access?

View File

@ -26,8 +26,6 @@ describe Travis::API::V3::Services::Account::Find do
before { get("/v3/account/example-org?organization.id=#{other.id}") }
example { expect(last_response).to be_ok }
pending "param whitelisting not yet implemented" do
example { expect(JSON.load(body)).to be == {
"@type" => "organization",
"@href" => "/v3/org/#{org.id}",
@ -38,7 +36,6 @@ describe Travis::API::V3::Services::Account::Find do
}}
end
end
end
describe "user" do
let(:user) { User.new(login: 'example-user') }
@ -65,10 +62,8 @@ describe Travis::API::V3::Services::Account::Find do
before { other.save! }
after { other.delete }
before { get("/v3/account/example-org?user.id=#{other.id}") }
before { get("/v3/account/example-user?user.id=#{other.id}") }
example { expect(last_response).to be_ok }
pending "param whitelisting not yet implemented" do
example { expect(JSON.load(body)).to be == {
"@type" => "user",
"@href" => "/v3/user/#{user.id}",
@ -81,5 +76,4 @@ describe Travis::API::V3::Services::Account::Find do
}}
end
end
end
end