mirror of
https://github.com/discourse/discourse.git
synced 2024-12-17 03:03:42 +08:00
SECURITY: Make sure uploaded_urls have corresponding upload records
This commit is contained in:
parent
f416634ea0
commit
5d062206db
|
@ -35,6 +35,9 @@ class Category < ActiveRecord::Base
|
||||||
|
|
||||||
validate :email_in_validator
|
validate :email_in_validator
|
||||||
|
|
||||||
|
validates :logo_url, upload_url: true
|
||||||
|
validates :background_url, upload_url: true
|
||||||
|
|
||||||
validate :ensure_slug
|
validate :ensure_slug
|
||||||
before_save :apply_permissions
|
before_save :apply_permissions
|
||||||
before_save :downcase_email
|
before_save :downcase_email
|
||||||
|
|
|
@ -9,6 +9,9 @@ class UserProfile < ActiveRecord::Base
|
||||||
before_save :cook
|
before_save :cook
|
||||||
after_save :trigger_badges
|
after_save :trigger_badges
|
||||||
|
|
||||||
|
validates :profile_background, upload_url: true
|
||||||
|
validates :card_background, upload_url: true
|
||||||
|
|
||||||
belongs_to :card_image_badge, class_name: 'Badge'
|
belongs_to :card_image_badge, class_name: 'Badge'
|
||||||
has_many :user_profile_views, dependent: :destroy
|
has_many :user_profile_views, dependent: :destroy
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,10 @@ module Discourse
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.base_protocol
|
||||||
|
SiteSetting.force_https? ? "https" : "http"
|
||||||
|
end
|
||||||
|
|
||||||
def self.base_url_no_prefix
|
def self.base_url_no_prefix
|
||||||
default_port = 80
|
default_port = 80
|
||||||
protocol = "http"
|
protocol = "http"
|
||||||
|
|
11
lib/validators/upload_url_validator.rb
Normal file
11
lib/validators/upload_url_validator.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class UploadUrlValidator < ActiveModel::EachValidator
|
||||||
|
def validate_each(record, attribute, value)
|
||||||
|
if value.present?
|
||||||
|
uri = URI.parse(value) rescue nil
|
||||||
|
|
||||||
|
unless uri && Upload.exists?(url: value)
|
||||||
|
record.errors[attribute] << (options[:message] || I18n.t('errors.messages.invalid'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -18,7 +18,7 @@ describe Discourse do
|
||||||
context 'base_url' do
|
context 'base_url' do
|
||||||
context 'when https is off' do
|
context 'when https is off' do
|
||||||
before do
|
before do
|
||||||
SiteSetting.expects(:use_https?).returns(false)
|
SiteSetting.use_https = false
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'has a non https base url' do
|
it 'has a non https base url' do
|
||||||
|
@ -28,7 +28,7 @@ describe Discourse do
|
||||||
|
|
||||||
context 'when https is on' do
|
context 'when https is on' do
|
||||||
before do
|
before do
|
||||||
SiteSetting.expects(:use_https?).returns(true)
|
SiteSetting.use_https = true
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'has a non-ssl base url' do
|
it 'has a non-ssl base url' do
|
||||||
|
@ -38,7 +38,7 @@ describe Discourse do
|
||||||
|
|
||||||
context 'with a non standard port specified' do
|
context 'with a non standard port specified' do
|
||||||
before do
|
before do
|
||||||
SiteSetting.stubs(:port).returns(3000)
|
SiteSetting.port = 3000
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns the non standart port in the base url" do
|
it "returns the non standart port in the base url" do
|
||||||
|
@ -63,7 +63,7 @@ describe Discourse do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns the system user otherwise' do
|
it 'returns the system user otherwise' do
|
||||||
SiteSetting.stubs(:site_contact_username).returns(nil)
|
SiteSetting.site_contact_username = nil
|
||||||
expect(Discourse.site_contact_user.username).to eq("system")
|
expect(Discourse.site_contact_user.username).to eq("system")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -76,10 +76,10 @@ describe Discourse do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns S3Store when S3 is enabled" do
|
it "returns S3Store when S3 is enabled" do
|
||||||
SiteSetting.stubs(:enable_s3_uploads?).returns(true)
|
SiteSetting.enable_s3_uploads = true
|
||||||
SiteSetting.stubs(:s3_upload_bucket).returns("s3_bucket")
|
SiteSetting.s3_upload_bucket = "s3bucket"
|
||||||
SiteSetting.stubs(:s3_access_key_id).returns("s3_access_key_id")
|
SiteSetting.s3_access_key_id = "s3_access_key_id"
|
||||||
SiteSetting.stubs(:s3_secret_access_key).returns("s3_secret_access_key")
|
SiteSetting.s3_secret_access_key = "s3_secret_access_key"
|
||||||
expect(Discourse.store).to be_a(FileStore::S3Store)
|
expect(Discourse.store).to be_a(FileStore::S3Store)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,24 @@ describe Category do
|
||||||
is_expected.to validate_uniqueness_of(:name).scoped_to(:parent_category_id)
|
is_expected.to validate_uniqueness_of(:name).scoped_to(:parent_category_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "url validation" do
|
||||||
|
let(:user) { Fabricate(:user) }
|
||||||
|
|
||||||
|
let(:upload) { Fabricate(:upload) }
|
||||||
|
|
||||||
|
it "ensures logo_url is valid" do
|
||||||
|
expect(Fabricate.build(:category, user: user, logo_url: "---%")).not_to be_valid
|
||||||
|
expect(Fabricate.build(:category, user: user, logo_url: "http://example.com/made-up.jpg")).not_to be_valid
|
||||||
|
expect(Fabricate.build(:category, user: user, logo_url: upload.url)).to be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "ensures background_url is valid" do
|
||||||
|
expect(Fabricate.build(:category, user: user, background_url: ";test")).not_to be_valid
|
||||||
|
expect(Fabricate.build(:category, user: user, background_url: "http://example.com/no.jpg")).not_to be_valid
|
||||||
|
expect(Fabricate.build(:category, user: user, background_url: upload.url)).to be_valid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it 'validates uniqueness in case insensitive way' do
|
it 'validates uniqueness in case insensitive way' do
|
||||||
Fabricate(:category, name: "Cats")
|
Fabricate(:category, name: "Cats")
|
||||||
cats = Fabricate.build(:category, name: "cats")
|
cats = Fabricate.build(:category, name: "cats")
|
||||||
|
|
|
@ -6,6 +6,23 @@ describe UserProfile do
|
||||||
expect(user.user_profile).to be_present
|
expect(user.user_profile).to be_present
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "url validation" do
|
||||||
|
let(:user) { Fabricate(:user) }
|
||||||
|
let(:upload) { Fabricate(:upload) }
|
||||||
|
|
||||||
|
it "ensures profile_background is valid" do
|
||||||
|
expect(Fabricate.build(:user_profile, user: user, profile_background: "---%")).not_to be_valid
|
||||||
|
expect(Fabricate.build(:user_profile, user: user, profile_background: "http://example.com/made-up.jpg")).not_to be_valid
|
||||||
|
expect(Fabricate.build(:user_profile, user: user, profile_background: upload.url)).to be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it "ensures background_url is valid" do
|
||||||
|
expect(Fabricate.build(:user_profile, user: user, card_background: ";test")).not_to be_valid
|
||||||
|
expect(Fabricate.build(:user_profile, user: user, card_background: "http://example.com/no.jpg")).not_to be_valid
|
||||||
|
expect(Fabricate.build(:user_profile, user: user, card_background: upload.url)).to be_valid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'rebaking' do
|
describe 'rebaking' do
|
||||||
it 'correctly rebakes bio' do
|
it 'correctly rebakes bio' do
|
||||||
user_profile = Fabricate(:evil_trout).user_profile
|
user_profile = Fabricate(:evil_trout).user_profile
|
||||||
|
|
Loading…
Reference in New Issue
Block a user