summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabio Pitino <fpitino@gitlab.com>2019-06-21 17:56:03 +0100
committerFabio Pitino <fpitino@gitlab.com>2019-07-11 10:26:53 +0200
commit1c42f748f8cac88692d3dca5470f74331e48b8d1 (patch)
tree4f77a7b5c9e088298112d6bf744c9d5bfcb93c12
parent0cd59a756cdee7aac8915f3e96ba4f065e5cbc9c (diff)
downloadgitlab-ce-1c42f748f8cac88692d3dca5470f74331e48b8d1.tar.gz
Don't display badges when builds are restricted
Badges were leaked to unauthorized users even when Public Builds project setting is disabled. Added guard clause to the controller to check if user can read build.
-rw-r--r--app/controllers/projects/badges_controller.rb3
-rw-r--r--changelogs/unreleased/security-fix-badges-leaked-to-unauthorized-users.yml5
-rw-r--r--spec/controllers/projects/badges_controller_spec.rb124
3 files changed, 101 insertions, 31 deletions
diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb
index 09a384e89ab..66b51b17790 100644
--- a/app/controllers/projects/badges_controller.rb
+++ b/app/controllers/projects/badges_controller.rb
@@ -3,7 +3,8 @@
class Projects::BadgesController < Projects::ApplicationController
layout 'project_settings'
before_action :authorize_admin_project!, only: [:index]
- before_action :no_cache_headers, except: [:index]
+ before_action :no_cache_headers, only: [:pipeline, :coverage]
+ before_action :authorize_read_build!, only: [:pipeline, :coverage]
def pipeline
pipeline_status = Gitlab::Badge::Pipeline::Status
diff --git a/changelogs/unreleased/security-fix-badges-leaked-to-unauthorized-users.yml b/changelogs/unreleased/security-fix-badges-leaked-to-unauthorized-users.yml
new file mode 100644
index 00000000000..9526f3c559f
--- /dev/null
+++ b/changelogs/unreleased/security-fix-badges-leaked-to-unauthorized-users.yml
@@ -0,0 +1,5 @@
+---
+title: Show badges if pipelines are public otherwise default to project permissions.
+erge_request:
+author:
+type: security
diff --git a/spec/controllers/projects/badges_controller_spec.rb b/spec/controllers/projects/badges_controller_spec.rb
index 5ec8d8d41d7..4ae29ba7f54 100644
--- a/spec/controllers/projects/badges_controller_spec.rb
+++ b/spec/controllers/projects/badges_controller_spec.rb
@@ -7,51 +7,115 @@ describe Projects::BadgesController do
let!(:pipeline) { create(:ci_empty_pipeline) }
let(:user) { create(:user) }
- before do
- project.add_maintainer(user)
- sign_in(user)
- end
+ shared_examples 'a badge resource' do |badge_type|
+ context 'when pipelines are public' do
+ before do
+ project.update!(public_builds: true)
+ end
+
+ context 'when project is public' do
+ before do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ end
+
+ it "returns the #{badge_type} badge to unauthenticated users" do
+ get_badge(badge_type)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'when project is restricted' do
+ before do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ project.add_guest(user)
+ sign_in(user)
+ end
+
+ it "returns the #{badge_type} badge to guest users" do
+ get_badge(badge_type)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
- it 'requests the pipeline badge successfully' do
- get_badge(:pipeline)
+ context 'format' do
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+ end
- expect(response).to have_gitlab_http_status(:ok)
- end
+ it 'renders the `flat` badge layout by default' do
+ get_badge(badge_type)
- it 'requests the coverage badge successfully' do
- get_badge(:coverage)
+ expect(response).to render_template('projects/badges/badge')
+ end
- expect(response).to have_gitlab_http_status(:ok)
- end
+ context 'when style param is set to `flat`' do
+ it 'renders the `flat` badge layout' do
+ get_badge(badge_type, 'flat')
- it 'renders the `flat` badge layout by default' do
- get_badge(:coverage)
+ expect(response).to render_template('projects/badges/badge')
+ end
+ end
- expect(response).to render_template('projects/badges/badge')
- end
+ context 'when style param is set to an invalid type' do
+ it 'renders the `flat` (default) badge layout' do
+ get_badge(badge_type, 'xxx')
+
+ expect(response).to render_template('projects/badges/badge')
+ end
+ end
- context 'when style param is set to `flat`' do
- it 'renders the `flat` badge layout' do
- get_badge(:coverage, 'flat')
+ context 'when style param is set to `flat-square`' do
+ it 'renders the `flat-square` badge layout' do
+ get_badge(badge_type, 'flat-square')
- expect(response).to render_template('projects/badges/badge')
+ expect(response).to render_template('projects/badges/badge_flat-square')
+ end
+ end
end
- end
- context 'when style param is set to an invalid type' do
- it 'renders the `flat` (default) badge layout' do
- get_badge(:coverage, 'xxx')
+ context 'when pipelines are not public' do
+ before do
+ project.update!(public_builds: false)
+ end
- expect(response).to render_template('projects/badges/badge')
+ context 'when project is public' do
+ before do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ end
+
+ it 'returns 404 to unauthenticated users' do
+ get_badge(badge_type)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when project is restricted to the user' do
+ before do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ project.add_guest(user)
+ sign_in(user)
+ end
+
+ it 'defaults to project permissions' do
+ get_badge(:coverage)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
end
end
- context 'when style param is set to `flat-square`' do
- it 'renders the `flat-square` badge layout' do
- get_badge(:coverage, 'flat-square')
+ describe '#pipeline' do
+ it_behaves_like 'a badge resource', :pipeline
+ end
- expect(response).to render_template('projects/badges/badge_flat-square')
- end
+ describe '#coverage' do
+ it_behaves_like 'a badge resource', :coverage
end
def get_badge(badge, style = nil)