mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 15:25:35 +08:00
SECURITY: Make sure uploaded_urls have corresponding upload records
This commit is contained in:
parent
cf5b756b1a
commit
2891f230d1
|
@ -36,6 +36,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
|
||||||
|
|
||||||
|
|
|
@ -186,9 +186,13 @@ module Discourse
|
||||||
ActionController::Base.config.relative_url_root.presence || default_value
|
ActionController::Base.config.relative_url_root.presence || default_value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.base_protocol
|
||||||
|
SiteSetting.force_https? ? "https" : "http"
|
||||||
|
end
|
||||||
|
|
||||||
def self.base_url_no_prefix
|
def self.base_url_no_prefix
|
||||||
protocol, default_port = SiteSetting.force_https? ? ["https", 443] : ["http", 80]
|
default_port = SiteSetting.force_https? ? 443 : 80
|
||||||
url = "#{protocol}://#{current_hostname}"
|
url = "#{base_protocol}://#{current_hostname}"
|
||||||
url << ":#{SiteSetting.port}" if SiteSetting.port.to_i > 0 && SiteSetting.port.to_i != default_port
|
url << ":#{SiteSetting.port}" if SiteSetting.port.to_i > 0 && SiteSetting.port.to_i != default_port
|
||||||
url
|
url
|
||||||
end
|
end
|
||||||
|
|
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(:force_https?).returns(false)
|
SiteSetting.force_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(:force_https?).returns(true)
|
SiteSetting.force_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
|
||||||
|
|
|
@ -339,7 +339,7 @@ describe User do
|
||||||
|
|
||||||
it 'returns false if user is not the only admin' do
|
it 'returns false if user is not the only admin' do
|
||||||
admin = Fabricate(:admin)
|
admin = Fabricate(:admin)
|
||||||
second_admin = Fabricate(:admin)
|
Fabricate(:admin)
|
||||||
|
|
||||||
expect(admin.is_singular_admin?).to eq(false)
|
expect(admin.is_singular_admin?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user