Skip to content
Snippets Groups Projects
Commit 256b9063 authored by GitLab Release Tools Bot's avatar GitLab Release Tools Bot
Browse files

Merge remote-tracking branch 'dev/12-6-stable' into 12-6-stable

parents 52a6715d c1c07df4
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -69,13 +69,39 @@ shared_examples 'handle uploads' do
end
 
describe "GET #show" do
let(:filename) { "rails_sample.jpg" }
let(:upload_service) do
UploadService.new(model, jpg, uploader_class).execute
end
let(:show_upload) do
get :show, params: params.merge(secret: secret, filename: "rails_sample.jpg")
get :show, params: params.merge(secret: secret, filename: filename)
end
 
before do
allow(FileUploader).to receive(:generate_secret).and_return(secret)
UploadService.new(model, jpg, uploader_class).execute
upload_service
end
context 'when the secret is invalid' do
let(:secret) { "../../../../../../../../" }
let(:filename) { "Gemfile.lock" }
let(:upload_service) { nil }
it 'responds with status 404' do
show_upload
expect(response).to have_gitlab_http_status(:not_found)
end
it 'is a working exploit without the validation' do
allow_any_instance_of(FileUploader).to receive(:secret) { secret }
show_upload
expect(response).to have_gitlab_http_status(:ok)
end
end
 
context 'when accessing a specific upload via different model' do
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@ describe FileMover do
 
let(:user) { create(:user) }
let(:filename) { 'banana_sample.gif' }
let(:secret) { 'secret55' }
let(:secret) { SecureRandom.hex }
let(:temp_file_path) { File.join("uploads/-/system/user/#{user.id}", secret, filename) }
 
let(:temp_description) do
Loading
Loading
@@ -47,8 +47,8 @@ describe FileMover do
subject
 
expect(snippet.reload.description)
.to eq("test ![banana_sample](/uploads/-/system/personal_snippet/#{snippet.id}/secret55/banana_sample.gif) "\
"same ![banana_sample](/uploads/-/system/personal_snippet/#{snippet.id}/secret55/banana_sample.gif) ")
.to eq("test ![banana_sample](/uploads/-/system/personal_snippet/#{snippet.id}/#{secret}/banana_sample.gif) "\
"same ![banana_sample](/uploads/-/system/personal_snippet/#{snippet.id}/#{secret}/banana_sample.gif) ")
end
 
it 'updates existing upload record' do
Loading
Loading
@@ -75,8 +75,8 @@ describe FileMover do
subject
 
expect(snippet.reload.description)
.to eq("test ![banana_sample](/uploads/-/system/user/#{user.id}/secret55/banana_sample.gif) "\
"same ![banana_sample](/uploads/-/system/user/#{user.id}/secret55/banana_sample.gif) ")
.to eq("test ![banana_sample](/uploads/-/system/user/#{user.id}/#{secret}/banana_sample.gif) "\
"same ![banana_sample](/uploads/-/system/user/#{user.id}/#{secret}/banana_sample.gif) ")
end
 
it 'does not change the upload record' do
Loading
Loading
@@ -101,8 +101,8 @@ describe FileMover do
subject
 
expect(snippet.reload.description)
.to eq("test ![banana_sample](/uploads/-/system/personal_snippet/#{snippet.id}/secret55/banana_sample.gif) "\
"same ![banana_sample](/uploads/-/system/personal_snippet/#{snippet.id}/secret55/banana_sample.gif) ")
.to eq("test ![banana_sample](/uploads/-/system/personal_snippet/#{snippet.id}/#{secret}/banana_sample.gif) "\
"same ![banana_sample](/uploads/-/system/personal_snippet/#{snippet.id}/#{secret}/banana_sample.gif) ")
end
 
it 'creates new target upload record an delete the old upload' do
Loading
Loading
@@ -121,8 +121,8 @@ describe FileMover do
subject
 
expect(snippet.reload.description)
.to eq("test ![banana_sample](/uploads/-/system/user/#{user.id}/secret55/banana_sample.gif) "\
"same ![banana_sample](/uploads/-/system/user/#{user.id}/secret55/banana_sample.gif) ")
.to eq("test ![banana_sample](/uploads/-/system/user/#{user.id}/#{secret}/banana_sample.gif) "\
"same ![banana_sample](/uploads/-/system/user/#{user.id}/#{secret}/banana_sample.gif) ")
end
 
it 'does not change the upload record' do
Loading
Loading
@@ -138,12 +138,8 @@ describe FileMover do
let(:temp_file_path) { File.join("uploads/-/system/user/#{user.id}", '..', 'another_subdir_of_temp') }
 
it 'does not trigger move if path is outside designated directory' do
stub_file_mover("uploads/-/system/user/#{user.id}/another_subdir_of_temp")
expect(FileUtils).not_to receive(:move)
subject
expect(snippet.reload.description).to eq(temp_description)
expect { subject }.to raise_error(FileUploader::InvalidSecret)
end
end
 
Loading
Loading
Loading
Loading
@@ -6,7 +6,8 @@ describe FileUploader do
let(:group) { create(:group, name: 'awesome') }
let(:project) { create(:project, :legacy_storage, namespace: group, name: 'project') }
let(:uploader) { described_class.new(project, :avatar) }
let(:upload) { double(model: project, path: 'secret/foo.jpg') }
let(:upload) { double(model: project, path: "#{secret}/foo.jpg") }
let(:secret) { "55dc16aa0edd05693fd98b5051e83321" } # this would be nicer as SecureRandom.hex, but the shared_examples breaks
 
subject { uploader }
 
Loading
Loading
@@ -14,7 +15,7 @@ describe FileUploader do
include_examples 'builds correct paths',
store_dir: %r{awesome/project/\h+},
upload_path: %r{\h+/<filename>},
absolute_path: %r{#{described_class.root}/awesome/project/secret/foo.jpg}
absolute_path: %r{#{described_class.root}/awesome/project/55dc16aa0edd05693fd98b5051e83321/foo.jpg}
end
 
context 'legacy storage' do
Loading
Loading
@@ -51,11 +52,11 @@ describe FileUploader do
end
 
describe 'initialize' do
let(:uploader) { described_class.new(double, secret: 'secret') }
let(:uploader) { described_class.new(double, secret: secret) }
 
it 'accepts a secret parameter' do
expect(described_class).not_to receive(:generate_secret)
expect(uploader.secret).to eq('secret')
expect(uploader.secret).to eq(secret)
end
end
 
Loading
Loading
@@ -154,8 +155,39 @@ describe FileUploader do
 
describe '#secret' do
it 'generates a secret if none is provided' do
expect(described_class).to receive(:generate_secret).and_return('secret')
expect(uploader.secret).to eq('secret')
expect(described_class).to receive(:generate_secret).and_return(secret)
expect(uploader.secret).to eq(secret)
expect(uploader.secret.size).to eq(32)
end
context "validation" do
before do
uploader.instance_variable_set(:@secret, secret)
end
context "32-byte hexadecimal" do
let(:secret) { SecureRandom.hex }
it "returns the secret" do
expect(uploader.secret).to eq(secret)
end
end
context "10-byte hexadecimal" do
let(:secret) { SecureRandom.hex(10) }
it "returns the secret" do
expect(uploader.secret).to eq(secret)
end
end
context "invalid secret supplied" do
let(:secret) { "%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Fgrafana%2Fconf%2F" }
it "raises an exception" do
expect { uploader.secret }.to raise_error(described_class::InvalidSecret)
end
end
end
end
 
Loading
Loading
Loading
Loading
@@ -6,12 +6,13 @@ describe PersonalFileUploader do
let(:model) { create(:personal_snippet) }
let(:uploader) { described_class.new(model) }
let(:upload) { create(:upload, :personal_snippet_upload) }
let(:secret) { SecureRandom.hex }
 
subject { uploader }
 
shared_examples '#base_dir' do
before do
subject.instance_variable_set(:@secret, 'secret')
subject.instance_variable_set(:@secret, secret)
end
 
it 'is prefixed with uploads/-/system' do
Loading
Loading
@@ -23,12 +24,12 @@ describe PersonalFileUploader do
 
shared_examples '#to_h' do
before do
subject.instance_variable_set(:@secret, 'secret')
subject.instance_variable_set(:@secret, secret)
end
 
it 'is correct' do
allow(uploader).to receive(:file).and_return(double(extension: 'txt', filename: 'file_name'))
expected_url = "/uploads/-/system/personal_snippet/#{model.id}/secret/file_name"
expected_url = "/uploads/-/system/personal_snippet/#{model.id}/#{secret}/file_name"
 
expect(uploader.to_h).to eq(
alt: 'file_name',
Loading
Loading
Loading
Loading
@@ -5,6 +5,9 @@ require 'spec_helper'
describe AddressableUrlValidator do
let!(:badge) { build(:badge, link_url: 'http://www.example.com') }
 
let(:validator) { described_class.new(validator_options.reverse_merge(attributes: [:link_url])) }
let(:validator_options) { {} }
subject { validator.validate(badge) }
 
include_examples 'url validator examples', described_class::DEFAULT_OPTIONS[:schemes]
Loading
Loading
@@ -114,6 +117,19 @@ describe AddressableUrlValidator do
end
end
 
context 'when blocked_message is set' do
let(:message) { 'is not allowed due to: %{exception_message}' }
let(:validator_options) { { blocked_message: message } }
it 'blocks url with provided error message' do
badge.link_url = 'javascript:alert(window.opener.document.location)'
subject
expect(badge.errors.first[1]).to eq 'is not allowed due to: Only allowed schemes are http, https'
end
end
context 'when allow_nil is set to true' do
let(:validator) { described_class.new(attributes: [:link_url], allow_nil: true) }
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment