From 28ff2f6848df713da8e3a3158c52d627da7a0896 Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Thu, 19 Nov 2015 19:24:18 +0100 Subject: [PATCH 1/7] aggressive blocking on /auth/github --- lib/travis/api/attack.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/travis/api/attack.rb b/lib/travis/api/attack.rb index 4d91ec31..66679446 100644 --- a/lib/travis/api/attack.rb +++ b/lib/travis/api/attack.rb @@ -44,7 +44,7 @@ class Rack::Attack # Ban time: 5 hours # Ban after: 10 POST requests within five minutes to /auth/github blacklist('hammering /auth/github') do |request| - Rack::Attack::Allow2Ban.filter(request.identifier, maxretry: 10, findtime: 5.minutes, bantime: bantime(5.hours)) do + Rack::Attack::Allow2Ban.filter(request.identifier, maxretry: 2, findtime: 5.minutes, bantime: bantime(5.hours)) do request.post? and request.path == '/auth/github' end end From 4f9cb29775f98b17386e5f6c1aef365f51074176 Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Thu, 19 Nov 2015 19:29:07 +0100 Subject: [PATCH 2/7] also add a throttle --- lib/travis/api/attack.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/travis/api/attack.rb b/lib/travis/api/attack.rb index 66679446..dc0a247d 100644 --- a/lib/travis/api/attack.rb +++ b/lib/travis/api/attack.rb @@ -59,6 +59,14 @@ class Rack::Attack end end + + ### + # Throttle: unauthenticated requests to /auth/github - 1 per minute + # Scoped by: IP address + throttle('req/ip/1min', limit: 1, period: 1.minute) do |request| + request.ip unless request.authenticated? and request.path == '/auth/github' + end + ### # Throttle: unauthenticated requests - 500 per minute # Scoped by: IP address From 8f5a34c7b67bcd541c2aca2c469acdcfac691c59 Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Thu, 19 Nov 2015 19:37:51 +0100 Subject: [PATCH 3/7] disable /auth/github --- lib/travis/api/app/endpoint/authorization.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/travis/api/app/endpoint/authorization.rb b/lib/travis/api/app/endpoint/authorization.rb index 122aa8e8..e73b97ce 100644 --- a/lib/travis/api/app/endpoint/authorization.rb +++ b/lib/travis/api/app/endpoint/authorization.rb @@ -78,6 +78,7 @@ class Travis::Api::App # # * **github_token**: GitHub token for checking authorization (required) post '/github' do + halt 503, "Endpoint temporarily disabled" unless settings.test? unless params[:github_token] halt 422, { "error" => "Must pass 'github_token' parameter" } end From b138fbcdeb3bbc38eff265ca0be3cdf98b04dbbe Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Thu, 19 Nov 2015 19:59:22 +0100 Subject: [PATCH 4/7] check user agent --- lib/travis/api/app/endpoint/authorization.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/travis/api/app/endpoint/authorization.rb b/lib/travis/api/app/endpoint/authorization.rb index e73b97ce..02998027 100644 --- a/lib/travis/api/app/endpoint/authorization.rb +++ b/lib/travis/api/app/endpoint/authorization.rb @@ -78,7 +78,7 @@ class Travis::Api::App # # * **github_token**: GitHub token for checking authorization (required) post '/github' do - halt 503, "Endpoint temporarily disabled" unless settings.test? + halt 503, "Endpoint temporarily disabled" unless settings.test? or request.user_agent =~ /^Travis/ unless params[:github_token] halt 422, { "error" => "Must pass 'github_token' parameter" } end From efb91d0a383cf4f3800ac50adcb071e8a3144baf Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Fri, 20 Nov 2015 13:53:35 +0100 Subject: [PATCH 5/7] move user-agent filter for /auth/github to redis --- lib/travis/api/app/endpoint/authorization.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/travis/api/app/endpoint/authorization.rb b/lib/travis/api/app/endpoint/authorization.rb index 02998027..41b06e75 100644 --- a/lib/travis/api/app/endpoint/authorization.rb +++ b/lib/travis/api/app/endpoint/authorization.rb @@ -78,7 +78,7 @@ class Travis::Api::App # # * **github_token**: GitHub token for checking authorization (required) post '/github' do - halt 503, "Endpoint temporarily disabled" unless settings.test? or request.user_agent =~ /^Travis/ + check_agent unless params[:github_token] halt 422, { "error" => "Must pass 'github_token' parameter" } end @@ -146,6 +146,16 @@ class Travis::Api::App private + def allowed_agents + @allowed_agents ||= redis.smembers('auth_agents') + end + + def check_agent + return if settings.test? or allowed_agents.empty? + return if allowed_agents.any? { |a| request.user_agent.to_s.start_with? a } + halt 403, "you are currently not allowed to perform this request. please contact support@travis-ci.com." + end + def serialize_user(user) rendered = Travis::Api.data(user, version: :v2) rendered['user'].merge('token' => user.tokens.first.try(:token).to_s) From 8f0b35a0f1e9b2777cce192fed210c3c5a82bcdb Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Fri, 20 Nov 2015 14:20:02 +0100 Subject: [PATCH 6/7] User-Agent-Tracker: check if comment is there --- lib/travis/api/app/middleware/user_agent_tracker.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/travis/api/app/middleware/user_agent_tracker.rb b/lib/travis/api/app/middleware/user_agent_tracker.rb index d7d582fa..c758e0f4 100644 --- a/lib/travis/api/app/middleware/user_agent_tracker.rb +++ b/lib/travis/api/app/middleware/user_agent_tracker.rb @@ -37,7 +37,7 @@ class Travis::Api::App end def mark_travis(agent) - command = agent.application.comment.detect { |c| c.start_with? "command " } + command = agent.application.comment.detect { |c| c.start_with? "command " } if agent.application.comment if command mark(:cli, :version, agent.version) From 4a3357a4888b424a1074d2f3c10df951467e185a Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Fri, 20 Nov 2015 16:24:26 +0100 Subject: [PATCH 7/7] v3: in access control object, avoid firing multiple permissions queries (even though they are cache hits) --- lib/travis/api/v3/access_control/user.rb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/travis/api/v3/access_control/user.rb b/lib/travis/api/v3/access_control/user.rb index e48bb577..5b6460fe 100644 --- a/lib/travis/api/v3/access_control/user.rb +++ b/lib/travis/api/v3/access_control/user.rb @@ -8,6 +8,7 @@ module Travis::API::V3 user = Models::User.find(user.id) if user.is_a? ::User @user = user @access_permissions = user.permissions.where(user_id: user.id) + @got_request = false super() end @@ -20,6 +21,7 @@ module Travis::API::V3 end def visible_repositories(list) + load_permissions list.where('repositories.private = false OR repositories.id IN (?)'.freeze, access_permissions.map(&:repository_id)) end @@ -47,7 +49,19 @@ module Travis::API::V3 def permission?(type, id) id = id.id if id.is_a? ::Repository - access_permissions.where(type => true, :repository_id => id).any? + + load_permissions if @got_request + @got_request = true + + if access_permissions.respond_to? :where + access_permissions.where(type => true, :repository_id => id).any? + else + access_permissions.any? { |p| p[type] == true and p.repository_id == id } + end + end + + def load_permissions + @access_permissions = @access_permissions.to_a end end end