Merge branch 'security-48259-private-snippet' into 'master'
[master] Prevent private snippet from being embeddable See merge request gitlab/gitlabhq!2692
This commit is contained in:
commit
8f461ef779
|
@ -75,7 +75,14 @@ class Projects::SnippetsController < Projects::ApplicationController
|
|||
format.json do
|
||||
render_blob_json(blob)
|
||||
end
|
||||
format.js { render 'shared/snippets/show'}
|
||||
|
||||
format.js do
|
||||
if @snippet.embeddable?
|
||||
render 'shared/snippets/show'
|
||||
else
|
||||
head :not_found
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -80,7 +80,13 @@ class SnippetsController < ApplicationController
|
|||
render_blob_json(blob)
|
||||
end
|
||||
|
||||
format.js { render 'shared/snippets/show' }
|
||||
format.js do
|
||||
if @snippet.embeddable?
|
||||
render 'shared/snippets/show'
|
||||
else
|
||||
head :not_found
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -130,12 +130,4 @@ module SnippetsHelper
|
|||
|
||||
link_to external_snippet_icon('download'), download_url, class: 'btn', target: '_blank', title: 'Download', rel: 'noopener noreferrer'
|
||||
end
|
||||
|
||||
def public_snippet?
|
||||
if @snippet.project_id?
|
||||
can?(nil, :read_project_snippet, @snippet)
|
||||
else
|
||||
can?(nil, :read_personal_snippet, @snippet)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -175,6 +175,12 @@ class Snippet < ActiveRecord::Base
|
|||
:visibility_level
|
||||
end
|
||||
|
||||
def embeddable?
|
||||
ability = project_id? ? :read_project_snippet : :read_personal_snippet
|
||||
|
||||
Ability.allowed?(nil, ability, self)
|
||||
end
|
||||
|
||||
def notes_with_associations
|
||||
notes.includes(:author)
|
||||
end
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
- if @snippet.updated_at != @snippet.created_at
|
||||
= edited_time_ago_with_tooltip(@snippet, placement: 'bottom', html_class: 'snippet-edited-ago', exclude_author: true)
|
||||
|
||||
- if public_snippet?
|
||||
- if @snippet.embeddable?
|
||||
.embed-snippet
|
||||
.input-group
|
||||
.input-group-prepend
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Prevent private snippets from being embeddable
|
||||
merge_request:
|
||||
author:
|
||||
type: security
|
|
@ -379,6 +379,46 @@ describe Projects::SnippetsController do
|
|||
end
|
||||
end
|
||||
|
||||
describe "GET #show for embeddable content" do
|
||||
let(:project_snippet) { create(:project_snippet, snippet_permission, project: project, author: user) }
|
||||
|
||||
before do
|
||||
sign_in(user)
|
||||
|
||||
get :show, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param, format: :js
|
||||
end
|
||||
|
||||
context 'when snippet is private' do
|
||||
let(:snippet_permission) { :private }
|
||||
|
||||
it 'responds with status 404' do
|
||||
expect(response).to have_gitlab_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when snippet is public' do
|
||||
let(:snippet_permission) { :public }
|
||||
|
||||
it 'responds with status 200' do
|
||||
expect(assigns(:snippet)).to eq(project_snippet)
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the project is private' do
|
||||
let(:project) { create(:project_empty_repo, :private) }
|
||||
|
||||
context 'when snippet is public' do
|
||||
let(:project_snippet) { create(:project_snippet, :public, project: project, author: user) }
|
||||
|
||||
it 'responds with status 404' do
|
||||
expect(assigns(:snippet)).to eq(project_snippet)
|
||||
expect(response).to have_gitlab_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #raw' do
|
||||
let(:project_snippet) do
|
||||
create(
|
||||
|
|
|
@ -80,6 +80,12 @@ describe SnippetsController do
|
|||
expect(assigns(:snippet)).to eq(personal_snippet)
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
end
|
||||
|
||||
it 'responds with status 404 when embeddable content is requested' do
|
||||
get :show, id: personal_snippet.to_param, format: :js
|
||||
|
||||
expect(response).to have_gitlab_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -106,6 +112,12 @@ describe SnippetsController do
|
|||
expect(assigns(:snippet)).to eq(personal_snippet)
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
end
|
||||
|
||||
it 'responds with status 404 when embeddable content is requested' do
|
||||
get :show, id: personal_snippet.to_param, format: :js
|
||||
|
||||
expect(response).to have_gitlab_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not signed in' do
|
||||
|
@ -131,6 +143,13 @@ describe SnippetsController do
|
|||
expect(assigns(:snippet)).to eq(personal_snippet)
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
end
|
||||
|
||||
it 'responds with status 200 when embeddable content is requested' do
|
||||
get :show, id: personal_snippet.to_param, format: :js
|
||||
|
||||
expect(assigns(:snippet)).to eq(personal_snippet)
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not signed in' do
|
||||
|
|
|
@ -423,4 +423,41 @@ describe Snippet do
|
|||
expect(blob.data).to eq(snippet.content)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#embeddable?' do
|
||||
context 'project snippet' do
|
||||
[
|
||||
{ project: :public, snippet: :public, embeddable: true },
|
||||
{ project: :internal, snippet: :public, embeddable: false },
|
||||
{ project: :private, snippet: :public, embeddable: false },
|
||||
{ project: :public, snippet: :internal, embeddable: false },
|
||||
{ project: :internal, snippet: :internal, embeddable: false },
|
||||
{ project: :private, snippet: :internal, embeddable: false },
|
||||
{ project: :public, snippet: :private, embeddable: false },
|
||||
{ project: :internal, snippet: :private, embeddable: false },
|
||||
{ project: :private, snippet: :private, embeddable: false }
|
||||
].each do |combination|
|
||||
it 'only returns true when both project and snippet are public' do
|
||||
project = create(:project, combination[:project])
|
||||
snippet = create(:project_snippet, combination[:snippet], project: project)
|
||||
|
||||
expect(snippet.embeddable?).to eq(combination[:embeddable])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'personal snippet' do
|
||||
[
|
||||
{ snippet: :public, embeddable: true },
|
||||
{ snippet: :internal, embeddable: false },
|
||||
{ snippet: :private, embeddable: false }
|
||||
].each do |combination|
|
||||
it 'only returns true when snippet is public' do
|
||||
snippet = create(:personal_snippet, combination[:snippet])
|
||||
|
||||
expect(snippet.embeddable?).to eq(combination[:embeddable])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue