There was a bug in timeline page.
Hyperlinks (<a>
) were unwanted escaped, showed in the page like below.
if a feedback is submitted in <a href="/about">About</a> page, ...
The fix is rather simple as below.
- <li><%= p %></li>
+ <li><%= p.html_safe %></li>
Basically, html_safe
tells rails not to HTML escape a string by claiming the string is “safe”
(doing nothing on the string but setting a flag).
html_safe
should not be called on any user input strings, otherwise you’ll be under risk of XSS attacks.
For this site, the fix is safe since all the content in the timeline page is solely input by myself,
not by other malicious users.
More about html_safe
html_safe
is a method of SafeBuffer, which is a String
wrapper designed to prevent XSS attack.
SafeBuffer
is almost the same as String
, beside having a difference behavior on concatenation.
When a “safe” SafeBuffer
A is appended by an “unsafe” SafeBuffer
or String
B, B will be HTML
escaped before concatenation. By default a SafeBuffer
/String
is not marked safe.
Rails uses SafeBuffer
to prevent XSS attack. For the below erb,
<li><%= p %></li>
Rails translates it into something like,
'<li>'.html_safe + p + '<li>'.html_safe
Therefore, p
, which may be from user input, is HTML escaped when concatenated, and rendered safely in the result page.
More than One Way in Ruby
Using raw
has the same effect, but show the intention in a much clearer way.
<li><%= raw p %></li>
And one more, <%==
is equivalent to raw
, in case you really want to save some keystrokes.