views:

75

answers:

3

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?

A: 

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.

erik
So how do I go about preserving the markup that is generated by TinyMCE if I escape the tags in the front end. For example, if I create a comment with bold text, then the following string is stored in the backend: "<strong>text</strong>". I want the user to see bold text when that is rendered in the front end, not the literal string with html markup tags.
Eric Ryan
That's where <%= sanitize(my_string) %> comes in. It will only escape bad tags like <script> but let safe ones render properly like <strong> and <em>.
erik
+1  A: 

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

&lt;tag&gt;

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().

nowk
A: 

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.

mtyaka