Rails - Outputting content, sanitize or <%=h? - ruby-on-rails

I recently made a small rails3 app to convert an old cms written in another language. After migrating the content I am having problems outputting content from the database.
The #content.desc field sometimes has html. Currently the only way I could get it to work was:
<%= sanitize content.desc %>
But is this the best way? When I use <%=h #content.desc %> I can see the html tags still. When I use <%= simple_format #content.desc %> I get wicked spacing.
Is there a definitive guide somewhere where I can see all of the options while outputting content? I've tried to search but can't turn anything up (rails newb, i know).

Any string not marked as "safe" will be HTML-escaped by default in Rails 3. Some methods, such as sanitize, h, link_to and many other helpers return safe strings, thus allowing them to be written literally. See this blog post for more info.
If you know for sure that the HTML contained in #content.desc is safe, you can mark it as such yourself like so: <%= #content.desc.html_safe %>.

Rails 3 has changed HTML sanitisation to be enabled by default. If you're sure that the string you're rendering is safe, you can use
<%= #content.desc.html_safe! %>

Unless I'm mistaken, you shouldn't have to sanitize the content before displaying it, as Rails 3 does that by default. More info here: http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/

Related

Safe Rails HTML translations

Following the rails guides as per the posting title, the YAML local files were set in a Rails 6.1.3 application as follows:
authorisation_request: Payment to be authorised; </br>Final <b>exact charge</b> </br>will reflect <b>delivered goods</b>.
authorisation_request_html: Payment to be authorised; </br>Final <b>exact charge</b> </br>will reflect <b>delivered goods</b>.
In the view, three experiments were conducted:
<i><%= t('cart.authorisation_request').capitalize %></i>
<i><%= raw t('cart.authorisation_request_html').capitalize %></i>
<i><%= t('cart.authorisation_request_html').capitalize %></i>
The first one rendered the tags as expected straight text, the middle one rendered as expected both the break and bold tags.
But the last one was rendered identical to the first. What am I missing?
When a translation key has the _html suffix, you can call it as if it did not, and it will automatically treat the key as HTML safe.
The way you are displaying the translation key is not as intended, instead of doing:
<%= t('cart.authorisation_request_html').capitalize %>
You should be doing:
<%= t('cart.authorisation_request').capitalize %>
Then the I18n system will see that there is an _html-suffixed variant, and mark that as HTML safe to display as-is. The way you are doing it now, the system would be looking for a key named authorization_request_html_html (double suffixed) and not find it.
More info on Safe HTML Translations: https://guides.rubyonrails.org/i18n.html#using-safe-html-translations
As a side-note, you should probably be capitalizing your source translated text, and not modifying it afterwards with the .capitalize helper. If that text were translated to another language, the capitalization could probably look pretty strange in some languages.

Rails 4: how to insert line breaks in text_area?

I have created a blog in rails. I'm a beginner and got quite far, but now I'm stuck with a seemingly minor detail: I can't seem to format the posts (articles).
Here's the relevant part of my show.html.erb:
<p>
<strong>Content:</strong>
<%= simple_format (#article.content) %>
</p>
When I write something and insert html-tags, they are not recognized as such. What am I doing wrong?
Rails will automatically remove html tags to prevent someone from injecting code into your webpage (e.g. malicious javascript)
If your users cannot enter data into #article.content and it's always safe then you can flag it as safe usng the html_safe method.
<%= (simple_format (#article.content)).html_safe %>
Can you post the article content for reference? If I had to guess, I'd imagine Rails is escaping the html tags and inserting them as plain text (so the output looks like: Article content !
Take a look at Rails' helper methods like content_tag (http://apidock.com/rails/ActionView/Helpers/TagHelper/content_tag) and concat (http://apidock.com/rails/ActionView/Helpers/TextHelper/concat) and consider using those to help with generating the appropriate html tags.
An issue to be concerned with is who's going to be supplying the content. For example, if you're writing an application that other people will use, you want to make sure any html give you is escaped to avoid XSS attacks. In that case, you'll want to spend some time reading about how to properly sanitize user input.
You can now specify the tag it gets wrapped in (defaults to p) like so:
<%= simple_format (#article.content, {}, wrapper_tag: "div") %>
or
add white-space: pre-line style.
It will display \r or \n (enter) in user input as a new line.
for more info:
http://apidock.com/rails/v4.0.2/ActionView/Helpers/TextHelper/simple_format

Rails DON'T sanitize

I am making a web app that integrates the Ace online IDE. A user enters an input through the Ace IDE which is then stored in a database. But when that is then rendered from the database Rails has done some sort of sanitization and the HTML tags are not loaded.
How do I explicitly tell Rails to leave all HTML tags in the tags and not format it (includes tabs and spaces)?
EDIT:
This is what the user inputs:
And this is what it outputs:
Try the raw method. This method outputs without escaping a string
you have to append .html_safe to any string you're returning to the view. By default Rails doesn't trust anything the user might have created.
So
<%= #my_source_code_from_the_db %>
Becomes
<%= #my_source_code_from_the_db.html_safe %>
As #Sam_D mentioned, another option is to wrap your string in a call to raw:
<%= raw(#my_source_code_from_the_db) %>
Turns out it was because I was using simple_format() when I removed that and just simply called <%= #lesson.lesson_content %> it rendered perfectly.

Are there any better alternatives to Sanitize for a Ruby app?

I love Sanitize. It's an amazing utility. The only issue I have w/ it is the fact that it takes forever to prepare a development environment w/ it because it uses Nokogiri, which is a pain for compile time. Are there any programs that do what Sanitize does (if nothing else than mildly what it does) w/out using Nokogiri? This would help exponentially!
Rails has its own SanitizeHelper.
According to http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html, it will
This sanitize helper will html encode all tags and strip all attributes that aren’t specifically allowed.
It also strips href/src tags with invalid protocols, like javascript: especially. It does its best to counter any tricks that hackers may use, like throwing in unicode/ascii/hex values to get past the javascript: filters. Check out the extensive test suite.
You can use it in a view like so
<%= sanitize #article.body %>
You can visit the link to see more customizing options like:
Custom Use (only the mentioned tags and attributes are allowed, nothing else)
<%= sanitize #article.body, tags: %w(table tr td), attributes: %w(id class style) %>

Adding Markdown into my Rails 3 app

I am trying to add Markdown to my Rails 3 web app but am having problems.
I have tried rdiscount and markdownizer but either they're not working or I'm not writing the correct code for them.
The code I have at the moment to display a text field is <%=h simple_format (#user.desktopinfo) %>
I want to increase the functionality of this text by adding Markdown but I am unable to get it work, please help! :)
EDIT 2
Using markdownizer broke my app, so I am now using BlueCloth. Add bluecloth to the gem file and add this <%= raw BlueCloth.new(#user.desktopinfo).to_html %>
:)
EDIT
Actually, just trying again...
With markdownizer, with markdownize! :desktopinfo in the user model and <%= #user.rendered_desktopinfo %> on the page that shows the text, I get this: <h1>this is a h1</h1> on the text when I enter
this is a h1
============
so I am halfway there! How do I now turn this code into html?
Consider rdiscount which substitutes for bluecloth but is faster and better maintained.
Ryan Tomayko's comparison is a good write up regarding the different libraries for using markdown in Ruby.
You haven't really specified exactly what you are after, but I use bluecloth when working with markdown. You can add 'bluecloth' to your Gemfile.
To parse your markdown it is as simple as:
<%= raw BlueCloth.new(YOUR_MARKDOWN).to_html %>
You need the keyword raw. so the HTML is not escaped.
<%= raw #user.rendered_desktopinfo %>

Resources