Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Escaping HTML in Rails

Tags:

What is the recommended way to escape HTML to prevent XSS vulnerabilities in Rails apps?

Should you allow the user to put any text into the database but escape it when displaying it? Should you add before_save filters to escape the input?

like image 595
readonly Avatar asked Mar 30 '09 19:03

readonly


People also ask

How do I stop HTML from escaping?

The html_safe method marks a string as being safe for insertion into HTML without escaping being performed.

What is escaping HTML?

Escaping in HTML means, that you are replacing some special characters with others. In HTML it means usally, you replace e. e.g < or > or " or & . These characters have special meanings in HTML. Imagine, you write <b>hello, world</b> And the text will appear as hello, world.

What is html_safe?

Marks a string as trusted safe. It will be inserted into HTML with no additional escaping performed.

How do you escape a string in Ruby?

When using strings in Ruby, we sometimes need to put the quote we used to define the string inside the string itself. When we do, we can escape the quote character with a backslash \ symbol.


Video Answer


1 Answers

There are three basic approaches to this problem.

  1. use h() in your views. The downside here is that if you forget, you get pwnd.
  2. Use a plugin that escapes content when it is saved. My plugin xss_terminate does this. Then you don't have to use h() in your views (mostly). There are others that work on the controller level. The downsides here are (a) if there's a bug in the escaping code, you could get XSS in your database; and (b) There are corner cases where you'll still want to use h().
  3. Use a plugin that escapes content when it is displayed. CrossSiteSniper is probably the best known of these. This aliases your attributes so that when you call foo.name it escapes the content. There's a way around it if you need the content unescaped. I like this plugin but I'm not wild about letting XSS into my database in the first place...

Then there are some hybrid approaches.

There's no reason why you can't use xss_terminate and CrossSiteSniper at the same time.

There's also a ERb implementation called Erubis that can be configured so that any call like <%= foo.name %> is escaped -- the equivalent of <%= h(foo.name) %>. Unfortunately, Erubis always seems to lag behind Rails and so using it can slow you down.

If you want to read more, I wrote a blog post (which Xavor kindly linked to) about using xss_terminate.

like image 88
Luke Francl Avatar answered Sep 20 '22 21:09

Luke Francl