diff --git a/app/models/feed.rb b/app/models/feed.rb index e056879af..b8e1a2e25 100644 --- a/app/models/feed.rb +++ b/app/models/feed.rb @@ -4,6 +4,7 @@ require 'schedule_manager' require 'feed_blacklister' require 'url_normalizer' +require 'sanitizer' ## # Feed model. Each instance of this model represents a single feed (Atom, RSS...) to which users can be suscribed. @@ -199,7 +200,7 @@ def single_user_folder(folder) # Various operations before each validation: # - fix any encoding problems, converting to utf-8 if necessary # - set default values for missing attributes - # - sanitize values, removing script tags from entry bodies etc. + # - sanitize values, removing script tags from titles etc. # - encode any invalid characters in url and fetch_url # - check if the feed url or fetch_url is blacklisted, and if so a BlacklistedUrlError is raised @@ -242,13 +243,9 @@ def default_values # the update only for that attribute and keep the old value. def sanitize_attributes - config = Feedbunch::Application.config.restricted_sanitizer - - self.title = Sanitize.fragment(self.title, config)&.strip - - # Unescape HTML entities in the URL escaped by the sanitizer - self.fetch_url = CGI.unescapeHTML(Sanitize.fragment(self.fetch_url, config)&.strip) - self.url = CGI.unescapeHTML(Sanitize.fragment(self.url, config)&.strip) + self.title = Sanitizer.sanitize_plaintext self.title + self.fetch_url = Sanitizer.sanitize_plaintext self.fetch_url + self.url = Sanitizer.sanitize_plaintext self.url # URLs must be valid http or https if self.fetch_url_was.present? && (self.fetch_url =~ URI::regexp(%w{http https})).nil? diff --git a/lib/sanitizer.rb b/lib/sanitizer.rb new file mode 100644 index 000000000..edf046d03 --- /dev/null +++ b/lib/sanitizer.rb @@ -0,0 +1,20 @@ +## +# Class with methods related to sanitizing user input to remove potentially malicious input. + +class Sanitizer + + ## + # Sanitize the passed string, removing any tags to leave only plain text. This avoids users entering malicious + # markup in text fields (e.g. URL field in subscribe popup). + # + # Receives as argument a string. + # + # If a nil or empty string is passed, returns nil. + + def self.sanitize_plaintext(unsanitized_text) + # Check that the passed string contains something + return nil if unsanitized_text.blank? + sanitized_text = ActionController::Base.helpers.strip_tags(unsanitized_text)&.strip + return sanitized_text + end +end