Reputation: 110950
Right now we're using the sanitize gem: https://github.com/rgrove/sanitize
Problem is if you enter "hello & world
" sanitize is saving that in the DB as:
hello & world
How can you whitelist the &
. We want sanitize to remove all possible malicious html and JS/script tags. but we're ok allowing the ampersand.
Ideas? Thanks
Upvotes: 14
Views: 6678
Reputation: 12203
None of the other answers worked for me. The best approach I've found for my use case was using the built in Loofah gem:
good = '&'
bad = "<script>alert('I am evil');</script>"
greater_than = '>' # << my use case
Loofah.fragment(good).text(encode_special_chars: false)
# => "&"
Loofah.fragment(greater_than).text(encode_special_chars: false)
# => ">"
Loofah.fragment(bad).text(encode_special_chars: false)
# => "alert('I am evil');"
# And just for clarity, without the option passed in:
Loofah.fragment(good).text
# => "&"
It's not flawless though, so be incredibly careful:
really_bad = "<script>alert('I am evil');</script>"
Loofah.fragment(really_bad).text(encode_special_chars: false)
# => "<script>alert('I am evil');</script>"
More info on the specified method here.
Definitely the most efficient approach for what I needed to do!
Upvotes: 2
Reputation: 18784
Sanitize will always transform what is output into html entities for valid html/xhtml.
The best way I can determine is filter the output
Sanitize.fragment("hello & world").gsub('&','&') #=> "Hello & world"
Upvotes: 6
Reputation: 31
As of Rails 4.2, #strip_tags
does not unencode HTML special chars
strip_tags("fun & co")
=> "fun & co"
Otherwise you'd get the following:
strip_tags("<script>")
=> "<script>"
If you only want the ampersand I'd suggest filtering the output like @Unixmonkey suggested and keep it to &
only
strip_tags("<bold>Hello & World</bold>").gsub(/&/, "&")
=> "Hello & World"
Upvotes: 1
Reputation: 710
UnixMonkey's answer is what we ended up doing.
def remove_markup(html_str)
marked_up = Sanitize.clean html_str
ESCAPE_SEQUENCES.each do |esc_seq, ascii_seq|
marked_up = marked_up.gsub('&' + esc_seq + ';', ascii_seq.chr)
end
marked_up
end
Where ESCAPE_SEQUENCES was an array of the characters we didn't want escaped.
Upvotes: 2
Reputation: 1254
Use the strip_tags() method instead.
http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html#method-i-sanitize
Upvotes: 3