Safely rendering a user's template/view? - ruby-on-rails

I have a model which has a template field. This template is HTML and has variables which get substituted. This template is then converted into a PDF using wicked_pdf.
How should I take the template which the user enters and safely do variable substitution? Allowing it to be an ERB template seems to be setting myself up for some huge security holes. What safe solutions are there?
Edit:
So, for example, I have my template class/model which has two fields, a name and an HTML field. This is a user editable class. There will be specific variables available to the HTML in the template class (Company Name, price, etc.). I am hoping to use a HTML templating system, but since this is user created content, it isn't trusted. Only variable substitution will be done, nothing more.

Rails provides a couple of helper functions, namely hto escape values on display for preventing such behavior.
<%= h #user.name %>
h is an alias of html_escape

Related

How to avoid html, iframe and cross site injection in rails?

I have stored the data in my database as html content.
Whenever user giving the input it will inject my html.
What should I do before storing into db I need to sanitize my data. Or I can store data whatever it. While displaying in view only I need to do something for injection.
I would recommend you to refer to the XSS Cross Site Scripting cheatsheet
and for Rails in particular, as stated:
The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements.
<%= sanitize #comment.body, tags: %w(strong em a), attributes: %w(href) %>

rails 5.x: add nofollow to all links in 'sanitize'

I am working on a Rails application whose HAML templates frequently make use of a routine called sanitize. I have deduced from context that this routine sanitizes user-controlled HTML. Example:
# views/feed_items/_about.html.haml
%h3 Summary:
.description
= sanitize #feed_item.description
I want to make this routine add 'rel=nofollow' to all outbound links, in addition to what it's already doing. What is the most straightforward way to do that?
N.B. I am not having any luck finding the definition of this method, or the official configuration knobs for it. The vendor directory has two different HTML sanitizer gems in it and I can't even figure out which one is being used. This is a large, complicated web application that I did not write, and I barely understand Ruby, let alone all of Rails' extensions to it. Please assume I do not know any of the things that you think are obvious.
The sanitizer will strip out the rel tags if they exist.
I ran into a similar issue and added an additional helper method - clean_links to the ApplicationHelper module, and called it after sanitizing the content.
# application_helper.rb
def clean_links html
html.gsub!(/\\2')
html.html_safe
end
This method looks for all <a> tags, and adds rel="nofollow". The html_safe method is necessary or else the HTML will be displayed as a string (it's already been sanitized).
This solution treats all links equally, so if you only want this for links pointing outside the domain, you'll have to update the REGEX accordingly.
In your view: <%= clean_links sanitize(#something) %>
So, first the content is sanitized, then you add the rel="nofollow" tag before displaying the link.
Actually there's a built-in way:
sanitize "your input", scrubber: Loofah::Scrubbers::NoFollow.new

What does the term "template" mean?

I am learning Rails 5.0, via a tutorial. Learning how to generate view templates, but the term "template" is never explicitly defined. I've searched in the Rails docs, and they seem to mention the word a lot, but also never really define it explicitly.
I know that views are the HTML, CSS associated with what the user sees. But was wondering what is a template and how is it different than a standard webpage?
I don't have an authoritative answer. But this is really rather simple. RoR lets you generate content dynamically. This means, with one template, you could generate different content (html pages). The final html page generated and served by the server is the webpage endusers see. For example, you could have a template show.html.erb with the following line:
<h> Product <%=#product.name%> </h>
From this template, different webpages for each different #product can be generated with that #product's name, depending on the #product variable, which is provided by the controller.
So templates allow you to dynamically generate content and render them as different html webpages.

In Rails, which is a better defender against XSS attacks, strip_tags or sanitize?

Assuming no tags are allowed in the user input and we want to sanitize user input before storing it in the database, in Rails, we have the options of using sanitize (whitelist an empty set of tags) and strip_tags.
Which is better against XSS attacks? If something else is even better, what is that? And why is it better?
As of Rails 3 and the fatty beatdown the Rails core dev team took when they made Rails unsafe by default, all strings are now tagged as either safe or unsafe with "unsafe" strings being the default. You only need to think about explicitly managing the "safeness" of strings in Rails when you're writing helpers that output HTML into your template.
Escaping vs Sanitizing:
In this context, escaping means replacing some of the string characters with an HTML escape sequence that will remove the special meaning from the text and cause it render as regular text. Sanitizing on the other hand, means validating the HTML content to ensure only good HTML tags and attributes are used. Note that sanitizing is inherently less secure than escaping because of this and should only be used where rendered content must contain HTML markup. An example would be a WYSIWYG HTML editor on a textarea that manages code that is later rendered on a page.
Sanitize encodes all tags and strips all attributes (not specifically allowed which is all in your case) from the html string passed to it. It also strips href and src tags with invalid protocols to prevent any abuse of js attributes. Strip_tags on the other hand will strip all supplied tags including comments which sounds like exactly what you want. As long as you're whitelisting params and adding them to your DB properly escaped such as:
Title.where(author = ?, author_id)
and not blindly inserting user input into your db I would be comfortable with how you're setup.

How to edit a model instance's text field (storing HTML) using markup/down editor?

(app is built on Rails 4.0.3/postgres)
I have a model defined where one of the attributes is a text field containing the entire HTML of a webpage- I store it as text, which I then set as an instance variable (#html) in the controller and then render it through a view using <%=raw #html %>. This allows me to store and render entire pages easily.
My question is, I need to allow users to edit the HTML in-browser using some kind of markup language/editor, so how would I go about doing so? The workflow would be that the user clicks on an instance of the model through a dashboard, and then is able to edit the name of model instance (easy), and under that is able to edit the html attribute and save it via some kind of markup editor like Github's gist editor. I feel like this should be easy but can't figure it out- can anyone point me in the right direction?
Thanks!

Resources