I have just implemented CKEditor for rich text entry in my app and I am thinking that the ability of a user to enter anything could pose a security threat.
At the moment, I have the simplest implementation - CKEditor sits in a form, input is saved to the database as part of update_attributes, and other people can view the output as html_safe.
Somehow, the above doesn't sound good to me, even though it works. Am I correct in thinking there are risks to the above approach? Is there a safer way to do this to block an attack through the editor?
You should always take care of sanitizing a users input. In your case, by stripping all unwanted HTML tags (like , for example) regardless of where it came from.
html_safe is not meant to strip HTML or sanitize for you. See Yehuda Katz' article on ActiveSupport::SafeBuffer. It is meant to prevent "unsafe" markup by marking a String as safe, if it is (and encoding it to HTML entities otherwise, to make it safe).
There are sanitation helpers in ActionView::Helpers::SanitizeHelper that you can use to sanitize what is displayed, but you might want to sanitize it before it enters the database.
If you strip away the possibility of inserting CSS, Javascript or an iframe, you should be fine. If you're paranoid about what your users do, also take away <img> tags. And if you're really paranoid, you should consider using Markdown, Textile or others.
Related
In Rails 4.2.4, say I have a form with a text field that a user can input whatever they want. I don't sanitize the input at all. The user then submits the form and to a controller method that looks like this:
def datahandler
#data = params[:usersdata]
end
Then in the related view, "datahandler.html.erb", I have the following:
<%= #data %>
Should be a huge XSS vulnerability right? Well it looks like Rails now automatically converts certain characters in string objects into CDATA representations for their views. This appears to break at least the XSS attack examples I've found.
However, I'm hesitant to rely on this mechanism without some research as I'm not an expert in XSS vulnerabilities. Further, the Rails Guides don't seem talk about this feature, even in their security guide (they talk about defending against XSS but they don't mention this feature). I haven't been able to find any documentation on this.
Can anyone point me to some documentation regarding this feature? If not, does anyone know of any loopholes in this protection (please provide examples)?
Rails' stock XSS protection is extremely bulletproof.
The default behavior was changed in Rails 3, to "escape HTML output ... by default in all view templates". Although there have been cases where the escaping needed to be adjusted, most of the known XSS vulnerabilities in Rails have not been centered around this functionality.
At any rate, the code in your question should be quite secure. The main problem with the current XSS protection in Rails is caused by developers misunderstanding the mechanics of the process. Taking the time to fully understand the implementation will ensure that you do not inadvertently introduce XSS errors in spite of the built in protection.
As far as I'm concerned, it doesn't do that by default but it has a protection mechanism which does that for you in case you'd want to use it http://guides.rubyonrails.org/security.html#injection
There's no scarcity of WYSIWYG editors, but it seems like there's no simple path to having one and keeping some semblance of protection from bypassing client side validation and including script and object tags.
My initial thought was to find a WYSIWYG editor which would output markdown, then store markdown formatted text in the db and parse on display. This would protect me from storing potentially dangerous code in the db, but also keep me from needing to whitelist every possible tag that the editor would put out as I would need to if it were HTML.
Am I missing some really easy path here? How does everyone else balance having a usable editor but not opening themselves wide open to attacks?
Ryan Grove's sanitize gem is very customizable, and I think the basic or relaxed modes would work for sanitizing raw html from the WYSIWYG editor (and you wouldn't have to whitelist a bunch of tags).
I am writing an app where a lot of heavy duty calculations are performed in the browser to generate and format some content. The resulting content is HTML that I would like to save on the server (structure, links, results of calculations, etc). It does not have any javascript or CSS (in style tags).
Is there a Rails method or plugin I can use in a model's before_save or after_initialize method to strip javascript/css from the content and safely send it back to the browser (via JSON, FYI) while preventing XSS attacks, given the simple structure of the content?
I personally use the Sanitize gem. Using this gem you can configure what HTML elements and attributes you want to allow and the gem will strip anything else.
I'd say this is a good choice for your app because since you want to allow some HTML but disallow Javascript/CSS then a sanitizer based on a full blown HTML parser is most likely the best choice considering there are numerous ways of being crafty and injecting Javascript/CSS into HTML.
Is there some gem or technique that will let us write only .html.erb templates for our Rails 3 mailers, and gracefully degrade them by stripping HTML tags for the text/plain version, rather than having to create each partial twice?
Google is seriously failing me, so I must be searching for the wrong terms.
take a look at premailer. It can generate text from html.
In general, this is not an easy problem. It might be easier if we were able to write semantic html markup and then it'd be easier to detect intent and convert the html into reasonable looking plain text.
But assuming your html emails are intended for a wide audience, it's full of all sorts of hacks that make the layout work in multiple email clients. This sort of dirty markup will make it harder to generate good looking plain text.
Another issue are things that won't clearly translate into text. Links that say "click here", will look funny in text, for example.
Well, if your html e-mail is simple and can be expressed as Markdown syntax you can use Markerb. It allows you to render multipart e-mails from a single template.
I'm currently in the process of writing my first Rails app. I'm writing a simple blog app that will allow users to comment on posts. I'm pretty new to Rails, so I'm looking for a bit of guidance on how to address security concerns with user input.
On the front end, I am using TinyMCE to accept user input. It is my understanding that TinyMCE will strip out any suspicious tags (e.g. <script>) from user input before posting to server. It seems that this could be bypassed by disabling javascript on the page, allowing a user to have free reign in the text area. TinyMCE recommends using javascript to create the TextArea. Therefore if the user disables javascript, there will be no text area. Is this the standard solution? It seems like a bit of a hack.
On the back end, what is the best way to strip out malicious code? Would I want to put some sort of validation in the create and update methods inside my comments controller? Is there some functionality built into Rails that can assist with this?
When displaying the information back out to the user, I'm assuming that I don't want to escape the HTML markup (with <%= h *text*%>), because that's how its stored in the back end. Is this bad practice?
I'm generally a big fan of cleaning out the data prior popping that stuff into the database. This is a debatable practice, but I usually lean toward this.
I use a modified version of the old white_list plugin to not strip out the html, but to convert anything I do want into a safer format.
<tag>
becomes
<tag>
This way I'm not really altering the content of the submission.
There are some plugins that specifically handle sanitization using a white/black list model.
http://github.com/rgrove/sanitize/ # Have not used, but looks very interesting
http://github.com/imanel/white_list_model # Used, not bad
There is also act_as_sanitized, but I have no real info on that.
And of course using the h().
Your suspicions are justified, but the creation of a text area in javascript won't make you any less vulnerable. A user could always use something like curl to force a form submission without ever visiting your site through a web browser.
You should assume that a user can post malicious scripts into the comments, and escape it on the frontend. Using <%= h(...) %> is one way to do it, or you can use the sanitize method in the same way. It will strip any scripts and escape all other html except for a few common tags that aren't harmful. Documentation for sanitize.
In addition to nowk's suggestions there is also the xss_terminate plugin. I have been using it in some of my applications. I found it to be easy to use, it needs almost no configuration, and has been working like a charm.