diff --git a/app/models/code_ocean/file.rb b/app/models/code_ocean/file.rb index 67796eae..bdbc3657 100644 --- a/app/models/code_ocean/file.rb +++ b/app/models/code_ocean/file.rb @@ -58,7 +58,7 @@ module CodeOcean def read if native_file? - valid = Pathname(native_file.current_path).fnmatch? ::File.join(native_file.root, '**') + valid = Pathname(native_file.current_path).realpath.fnmatch? ::File.join(native_file.root, '**') return nil unless valid native_file.read diff --git a/spec/models/code_ocean/file_spec.rb b/spec/models/code_ocean/file_spec.rb index 6a279a6d..3482cc6a 100644 --- a/spec/models/code_ocean/file_spec.rb +++ b/spec/models/code_ocean/file_spec.rb @@ -69,7 +69,26 @@ describe CodeOcean::File do end context 'when the path has been modified' do - before { file.update(native_file: '../../../../secrets.yml') } + before do + file.update_column(:native_file, '../../../../secrets.yml') # rubocop:disable Rails/SkipsModelValidations + file.reload + end + + it 'does not read the native file' do + expect(file.read).not_to be_present + end + end + + context 'when a symlink is used' do + let(:fake_upload_location) { File.join(CarrierWave::Uploader::Base.new.root, 'uploads', 'files', 'secrets.yml') } + + before do + File.symlink Rails.root.join('config/secrets.yml'), fake_upload_location + file.update_column(:native_file, '../secrets.yml') # rubocop:disable Rails/SkipsModelValidations + file.reload + end + + after { File.delete(fake_upload_location) } it 'does not read the native file' do expect(file.read).not_to be_present