v3: implement query params whitelisting to avoid argument injection attacks
This commit is contained in:
parent
5efdcc24c8
commit
51c2d1f0bf
|
@ -17,7 +17,7 @@ module Travis::API::V3
|
||||||
|
|
||||||
raise NotFound unless factory
|
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
|
result = service.run
|
||||||
render(result, env_params, env)
|
render(result, env_params, env)
|
||||||
rescue Error => error
|
rescue Error => error
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
module Travis::API::V3
|
module Travis::API::V3
|
||||||
class Service
|
class Service
|
||||||
|
DEFAULT_PARAMS = [ "include".freeze, "@type".freeze ]
|
||||||
|
private_constant :DEFAULT_PARAMS
|
||||||
|
|
||||||
def self.result_type(type = nil)
|
def self.result_type(type = nil)
|
||||||
@result_type = type if type
|
@result_type = type if type
|
||||||
@result_type ||= parent.result_type if parent and parent.respond_to? :result_type
|
@result_type ||= parent.result_type if parent and parent.respond_to? :result_type
|
||||||
|
@ -7,6 +10,20 @@ module Travis::API::V3
|
||||||
@result_type
|
@result_type
|
||||||
end
|
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
|
attr_accessor :access_control, :params
|
||||||
|
|
||||||
def initialize(access_control, params)
|
def initialize(access_control, params)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module Travis::API::V3
|
module Travis::API::V3
|
||||||
class Services::Repositories::ForCurrentUser < Service
|
class Services::Organizations::ForCurrentUser < Service
|
||||||
def run!
|
def run!
|
||||||
raise LoginRequired unless access_control.logged_in?
|
raise LoginRequired unless access_control.logged_in?
|
||||||
query.for_member(access_control.user)
|
query.for_member(access_control.user)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
module Travis::API::V3
|
module Travis::API::V3
|
||||||
class Services::Organizations::ForCurrentUser < Service
|
class Services::Repositories::ForCurrentUser < Service
|
||||||
|
params :active, :private, prefix: :repository
|
||||||
|
|
||||||
def run!
|
def run!
|
||||||
raise LoginRequired unless access_control.logged_in?
|
raise LoginRequired unless access_control.logged_in?
|
||||||
query.for_member(access_control.user)
|
query.for_member(access_control.user)
|
||||||
|
|
|
@ -5,6 +5,7 @@ module Travis::API::V3
|
||||||
private_constant :TIME_FRAME, :LIMIT
|
private_constant :TIME_FRAME, :LIMIT
|
||||||
|
|
||||||
result_type :request
|
result_type :request
|
||||||
|
params "request", "user", :config, :message, :branch
|
||||||
|
|
||||||
def run
|
def run
|
||||||
raise LoginRequired unless access_control.logged_in? or access_control.full_access?
|
raise LoginRequired unless access_control.logged_in? or access_control.full_access?
|
||||||
|
|
|
@ -26,17 +26,14 @@ describe Travis::API::V3::Services::Account::Find do
|
||||||
|
|
||||||
before { get("/v3/account/example-org?organization.id=#{other.id}") }
|
before { get("/v3/account/example-org?organization.id=#{other.id}") }
|
||||||
example { expect(last_response).to be_ok }
|
example { expect(last_response).to be_ok }
|
||||||
|
example { expect(JSON.load(body)).to be == {
|
||||||
pending "param whitelisting not yet implemented" do
|
"@type" => "organization",
|
||||||
example { expect(JSON.load(body)).to be == {
|
"@href" => "/v3/org/#{org.id}",
|
||||||
"@type" => "organization",
|
"id" => org.id,
|
||||||
"@href" => "/v3/org/#{org.id}",
|
"login" => "example-org",
|
||||||
"id" => org.id,
|
"name" => nil,
|
||||||
"login" => "example-org",
|
"github_id" => nil
|
||||||
"name" => nil,
|
}}
|
||||||
"github_id" => nil
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -65,21 +62,18 @@ describe Travis::API::V3::Services::Account::Find do
|
||||||
before { other.save! }
|
before { other.save! }
|
||||||
after { other.delete }
|
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 }
|
example { expect(last_response).to be_ok }
|
||||||
|
example { expect(JSON.load(body)).to be == {
|
||||||
pending "param whitelisting not yet implemented" do
|
"@type" => "user",
|
||||||
example { expect(JSON.load(body)).to be == {
|
"@href" => "/v3/user/#{user.id}",
|
||||||
"@type" => "user",
|
"id" => user.id,
|
||||||
"@href" => "/v3/user/#{user.id}",
|
"login" => "example-user",
|
||||||
"id" => user.id,
|
"name" => nil,
|
||||||
"login" => "example-user",
|
"github_id" => nil,
|
||||||
"name" => nil,
|
"is_syncing"=> nil,
|
||||||
"github_id" => nil,
|
"synced_at" => nil
|
||||||
"is_syncing"=> nil,
|
}}
|
||||||
"synced_at" => nil
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user