I'm building an application that has a HTML GUI interface to create, move and edit boxes (div) inside a container div. These boxes get assigned inline styles when editing, these inline styles are saved to the database and are output in the views:
<%= sanitize raw(#slide.content) %>
I want to sanitize the HTML itself, to avoid someone hacking in, for instance, a script tag, through sending that by editing what's sent to the server when the boxes are saved.
Rails 4 has a helper method sanitize available through the class ActionView::Helpers::SanitizeHelper. When I use this with a test content value that contains a malicious <script> tag, the script gets removed just fine. But sanitizing the content also strips CSS properties inside the style tag that are necessary for the boxes, like top, left, position, etc.
In the linked documentation, it's stated that sanitize will automatically use the function sanitize_css when it comes across a style attribute:
sanitize_css(style)
Sanitizes a block of CSS code. Used by sanitize when it comes across a style attribute.
I do not want this behaviour of sanitize. How can I disable sanitize using sanitize_css, to sanitize the HTML, but not the CSS?
You can allow any attributes and tags you need, so rails will skip them.
sanitize raw(#slide.content), tags: %w(table tr td ul li), attributes: %w(style href title)
Speaking about CSS rules themselves, it's a bit harder to allow additional rules, but still possible. You can monkey patch the HTML::WhiteListSanitizer class (https://github.com/rails/rails/blob/c71c8a962353642ee44b5cc6ed68dc18322eea72/actionpack/lib/action_view/vendor/html-scanner/html/sanitizer.rb). There are several attributes that can help.
In your config/application.rb file:
config.action_view.sanitized_allowed_tags = nil
config.action_view.sanitized_allowed_attributes = nil
safe lists found here: loofah html5 safelist
Related
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
With a grails app and from a local database, I'm returning some text in a xml format.
I can return it well formed in a <textarea></textarea> tag with the correct indenting (tabulation, line return,...etc.)
I want to go a bit further. In the text I'm returning, there are some <img/> tags and I'd like to replace those tag by the real images themselves.
I searched around and found no solution as of now. I understood that you can't add an image to a textarea (other then in a background), and if I choose a div tag, I won't have the indenting anymore (and therefore, harder to read)
I was wondering if using a <g:textField/> or an other tag from the grails library will do the trick. And if so, How can I append them to a page using jquery.
For example, how to append a <g:textField/> in jquery. It doesn't interpret it and I get this error
SyntaxError: missing ) after argument list [Break On This Error]...+doc).append("<input type="text" id="FTMAP_"+nb_sec+"" ...
And in my javascript file, I have
$("#FTM_"+doc).append("<g:textField id='FTMAP_"+nb_sec+"' ... />
Any possible solutions ?
EDIT
I did forget to mention that my final intentions are to be able to modify the text (tags included) and to have a nice and neat indentation so that it is the easiest possible for the end user.
You are asking a few different questions:
1. Can I use a single HTML tag to include images inside pre-formatted text.
No. You will have to parse the text and translate it into styled text yourself.
2. Is there a tag in the grails standard tags to accomplish this for me?
No.
3. How can I add grails tags from my javascript code.
Grails tags are processed on the server-side, and javascript is processed on the client. This means you cannot directly add grails tags via javascript.
There are a couple methods that can accomplish the same result, however:
You can set a javascript variable to the rendered content of a grails tag. This solution is good for data that is known at the time of the initial request.
var tagOutput = "${g.textField(/* etc */)}";
You can make an ajax request for the content to be added. Then your server-side grails code can render the tags you need. This is better for realtime data, or data that will be updated more than once on a single rendered page.
Throughout my site, users can leave comments. I want them to be able to insert basic HTML in their comments, including bold, italic, and link tags. Unfortunately, Rails automatically escapes all user-generated HTML.
I can bypass this behavior by calling .html_safe, but then I leave my site vulnerable to XSS. Is there a way to permit bold, italic, and link tags, while still escaping other content?
You can use something like markdown to support formatting via alternative (not html directly) means. Markdown can be supported via a number of rubygems, including Redcarpet, markitup, etc. Markdown creates an alternative syntax for bold/italics etc (like bbcode).
https://github.com/jwigal/markitup_rails
You can also use a whitelisting sanitizer like Loofah - https://github.com/flavorjones/loofah/. Loofah is a higher end solution, supporting any html tags you want. The users will submit HTML, then Loofah will read it, and build an html node tree using nokogiri. Then it traverses the tree making sure all tag nodes use whitelisted html tags, allowing you to allow any mix of tags you want, including <a>, <img>, <table> etc. It is highly configurable.
Loofah also checks the attributes (depending on configuration), to make sure nothing is hidden in forbidden attributes like onclick=""
I'm working on a pastebin clone. I need the user to be able to type in HTML without it being used like HTML. For example, my user types "<html> Hello, world! </html>", and the html tags don't appear because the text is being treated like HTML. I do not want this to happen.
I want this to happen to this line:
<%=simple_format(#post.content )%>
How could I accomplish this? I tried using raw and .html_safe and they didn't work.
The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements. These helper methods extend Action View making them callable within your template files.
http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html
Anyone who's done anything much with PHP and receiving rich-text input from something like TinyMCE has (probably) used something like HTMLPurifier to keep the nasties out of the HTML you're intentionally allowing the user to submit.
For example, HTMLPurifier will take a string of (potentially malformed) HTML and strip out disallowed elements and attributes, try to fix broken HTML, and in some cases convert things like <i> to <em>.
Does anything equivalent exist for Rails (3)? What's the generally accepted way to sanitize input from rich text editors in Rails so that you can output the unescaped HTML onto a web page and know that stuff like <style> and <script> tags have been taken out of it and it's not going to break your page (or steal your cookies!)?
EDIT | Anybody used Sanitize? Any other options with pro's & con's?
You can use the sanitize method.
sanitize(html)
There is also a Sanitize gem.
Sanitize.clean(html)
I tend to prefer the Sanitize gem because it can be used as a before_save filter in your models instead of having to use the sanitize method in each of your views.