3

I have an RHTML view in Rails, where the output is coming from my MongoDB collection. The data is outputted correctly using an iteration block, but whenever I try and have HTML tags in my database, they are not rendered in the HTML output, instead they are just displayed.

<%
 @posts.find().each do |post|
%>
 <h1><%=post["name"]%></h1>
 <p><%=post["body"] %></p>
 <p><%=post["timestamp"]%></p>
<%
 end
%>

But, for instance, if I had

<p>Test</p>

In my database, the tags would be rendered, instead of being printed.

2
  • You shouldn't need the find() after @posts Commented Dec 15, 2010 at 13:27
  • if @posts is a collection object he does Commented Dec 15, 2010 at 13:30

2 Answers 2

6

This is a security precaution that is now built into Rails 3. It prevents XSS (cross-site scripting) issues.

If you add raw you'll get the output you want.

<% @posts.each do |post| %> 
 <h1><%=raw post["name"]%></h1> 
 <p><%=raw post["body"] %></p> 
 <p><%=raw post["timestamp"]%></p> 
<% end %> 

However, if you are storing user-created arbitrary HTML, I don't recommend you do this unless you are sanitizing the input prior to storing it in the database.

Edit:

Another option: Using the sanitize helper in place of raw, e.g. <%=sanitize post["name"], :tags => "p" %> to allow <p> tags.

Sign up to request clarification or add additional context in comments.

Comments

2

Apart from raw and .html_safe, which give 100% trust to the user's input, you could also use sanitize to restrict only a number of tags that allowed.

<%= sanitize post["name"] $>

For the details, see: http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html

1 Comment

Good point about sanitize. +1 to you and I've updated my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.