diff --git a/app/models/topic.rb b/app/models/topic.rb
index 92951e1e543..8aa2c1e5bf9 100644
--- a/app/models/topic.rb
+++ b/app/models/topic.rb
@@ -65,6 +65,9 @@ class Topic < ActiveRecord::Base
before_validation do
+ if SiteSetting.title_sanitize
+ self.title = sanitize(title.to_s, tags: [], attributes: []).strip.presence
+ end
self.title = TextCleaner.clean_title(TextSentinel.title_sentinel(title).text) if errors[:title].empty?
end
@@ -241,14 +244,19 @@ class Topic < ActiveRecord::Base
end
def fancy_title
- sanitized_title = title.gsub(/['&\"<>]/, {
- "'" => ''',
- '&' => '&',
- '"' => '"',
- '<' => '<',
- '>' => '>',
- })
+ sanitized_title = if SiteSetting.title_sanitize
+ sanitize(title.to_s, tags: [], attributes: []).strip.presence
+ else
+ title.gsub(/['&\"<>]/, {
+ "'" => ''',
+ '&' => '&',
+ '"' => '"',
+ '<' => '<',
+ '>' => '>',
+ })
+ end
+ return unless sanitized_title
return sanitized_title unless SiteSetting.title_fancy_entities?
# We don't always have to require this, if fancy is disabled
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index dd624decff2..75038c5ce15 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -799,6 +799,7 @@ en:
max_similar_results: "How many similar topics to show a user while they are composing a new topic"
title_prettify: "Prevent common title typos and errors, including all caps, lowercase first character, multiple ! and ?, extra . at end, etc."
+ title_sanitize: "Remove html tags from the title"
topic_views_heat_low: "The number of views after which a topic's heat level is low."
topic_views_heat_medium: "The number of views after which a topic's heat level is medium."
diff --git a/config/site_settings.yml b/config/site_settings.yml
index e64c397a6a9..f32b740ecf1 100644
--- a/config/site_settings.yml
+++ b/config/site_settings.yml
@@ -185,6 +185,7 @@ posting:
default: 255
title_min_entropy: 10
title_prettify: true
+ title_sanitize: false
title_fancy_entities: true
min_private_message_title_length:
client: true
diff --git a/spec/models/topic_spec.rb b/spec/models/topic_spec.rb
index fd332debcdf..56eca86cde7 100644
--- a/spec/models/topic_spec.rb
+++ b/spec/models/topic_spec.rb
@@ -120,16 +120,40 @@ describe Topic do
let(:topic_image) { build_topic_with_title("Topic with image in its title" ) }
let(:topic_script) { build_topic_with_title("Topic with script in its title" ) }
- it "escapes script contents" do
- topic_script.fancy_title.should == "Topic with <script>alert(‘title’)</script> script in its title"
+ context "title_sanitize disabled" do
+
+ before { SiteSetting.stubs(:title_sanitize).returns(false) }
+
+ it "escapes script contents" do
+ topic_script.fancy_title.should == "Topic with <script>alert(‘title’)</script> script in its title"
+ end
+
+ it "escapes bold contents" do
+ topic_bold.fancy_title.should == "Topic with <b>bold</b> text in its title"
+ end
+
+ it "escapes image contents" do
+ topic_image.fancy_title.should == "Topic with <img src=‘something’> image in its title"
+ end
+
end
- it "escapes bold contents" do
- topic_bold.fancy_title.should == "Topic with <b>bold</b> text in its title"
- end
+ context "title_sanitize enabled" do
+
+ before { SiteSetting.stubs(:title_sanitize).returns(true) }
+
+ it "removes script contents" do
+ topic_script.fancy_title.should == "Topic with script in its title"
+ end
+
+ it "removes bold contents" do
+ topic_bold.fancy_title.should == "Topic with bold text in its title"
+ end
+
+ it "removes image contents" do
+ topic_image.fancy_title.should == "Topic with image in its title"
+ end
- it "escapes image contents" do
- topic_image.fancy_title.should == "Topic with <img src=‘something’> image in its title"
end
end
@@ -1330,7 +1354,7 @@ describe Topic do
end
describe "expandable_first_post?" do
- let(:topic) { Fabricate.build(:topic) }
+ let(:topic) { Fabricate.build(:topic) }
before do
SiteSetting.stubs(:embeddable_host).returns("http://eviltrout.com")