1
votes

I'm running Rails 4.2.x and I have the following problem.

The <title> of some pages are generated from user content. So I have to use the sanitize Rails helpers to properly clean it up.

But if the user writes something like "A & B", the title shown in browser is A &amp; B which is wrong.

What's the correct way of escaping user content on the <title> tag using Rails? At least some special characters should be included...

2
<%= title.html_safe %> should help. And see api.rubyonrails.org/classes/ActionView/Helpers/… - devanand
@devanand html_safe marks the user input as safe, whatever it contains... so that's the unsafest approach :-) - rubenfonseca
the link I gave you to read, explains how to make user input more secure! - devanand
@devanand I know how to make the input more secure, and in general, sanitize works great when we inject user input in the middle of the HTML. However in this case, the <title> tag is sensitive to HTML entities, so I don't want some of them to be escaped. - rubenfonseca
that's what I'd like to tell. use strip_tags in that case. or did I misunderstood? - devanand

2 Answers

1
votes

We can use CGi also

title =  "A & B"
=> "A & B"
string = CGI.escapeHTML(title)
=> "A &amp; B" 
string = CGI.unescapeHTML(title)
=> "A & B"

Rails providing so many options to escape

Refer these links:

raw vs. html_safe vs. h to unescape html

How to HTML encode/escape a string? Is there a built-in?

If you want remove tags you can use SanitizeHelper

One more option : WhiteListSanitizer

white_list_sanitizer = Rails::Html::WhiteListSanitizer.new
white_list_sanitizer.sanitize(s, tags: %w())
white_list_sanitizer.sanitize(s, tags: %w(table tr td), attributes: %w(id class style))

You can use Rails::Html::TargetScrubber also

0
votes

You can both sanitize and convert html entities to proper characters with a combination of sanitize and the htmlentities gem. This works for me in the console:

gem install htmlentities

then...

c = ActionController::Base::ApplicationController.new
dirty_content = "<script>content & tags</script>"
clean_but_with_entities = c.helpers.sanitize(dirty_content)
nice_looking = HTMLEntities.new.decode(clean_but_with_entities.to_str )

You end up with "content & tags". To make this easier to use I put this in application_controller:

helper_method :sanitize_and_decode
def sanitize_and_decode(str)
  helpers.sanitize(str)
  HTMLEntities.new.decode(str.to_str)
end

(to_str is to work around the SafeBuffer issue mentioned here)