#204
Mar 08, 2010

XSS Protection in Rails 3

It is easy to be vulnerable to cross site scripting attacks in earlier versions of Rails, but Rails 3 solves this by automatically escaping unsafe input.
Download (15.7 MB, 8:56)
alternative download for iPod & Apple TV (11.1 MB, 8:56)

Resources

Update: as Santiago pointed out in the comments, it looks like XSS protection has been back-ported to Rails 2.3 and will be available in Rails 2.3.6.

<!-- views/comments/_comment.html.erb -->
<div class="comment">
  <%= strong link_to(comment.name, comment.url) %>
  <p><%= comment.content %></p>
</div>
# rails c
"foo".html_safe?
safe = "safe".html_safe
safe.html_safe?

# application_helper.rb
def strong(content)
  "<strong>#{h(content)}</strong>".html_safe
end

RSS Feed for Episode Comments 30 comments

1. Ryan Mar 08, 2010 at 01:37

Awesome thanks again! We need screencast on mongodb and rails 3!


2. Skip Mar 08, 2010 at 01:45

Brilliant, thanks for all your efforts with the weekly railscasts.


3. Fredrik Mar 08, 2010 at 01:46

@Ryan No need for MongoDB screencasts. If you want updates on mongomapper you can read www.railstips.org

And there's always MongoID too =P


4. Steve Mar 08, 2010 at 02:18

Congratulations on never missing a beat in 3 years of doing this podcast! Your hard work is appreciated. Looks like rails 3 is coming up nicely. I cant wait till its out of beta.


5. Andrea Mar 08, 2010 at 02:33

Thanks Ryan, I am really loving this series of screencasts dedicated to the new rails 3 features.


6. Benjamin Lewis Mar 08, 2010 at 03:16

Wow. Well done!

Thank you very much.

Ben


7. Santiago Pastorino Mar 08, 2010 at 06:15

Ryan, with Rails 2-3-stable from git is not easy to be vulnerable anymore.
That's going to be released sooner with Rails 2.3.6

Take a look at
http://github.com/rails/rails/commit/9ca6df83f606a0fb8be3815328111d0cdaa7c65b
and
http://github.com/rails/rails_xss


8. Steve Byrne Mar 08, 2010 at 07:24

Congratulations on the 3 year anniversary! Not only do you make Mondays something to look forward to, but you've provided immeasurable value to the Rails community, helping newbies and not so newbies pick up and be able to use the latest, coolest Rails technologies.

Thank you very much for all you've done, and continue to do!

Steve


9. Yuval Mar 08, 2010 at 07:38

Happy ani!

Couple questions:

1) I assume the sanitize method still exists for selectively passing tags and attributes?

2) Does content_tag automatically apply html_safe? Would be pretty cumbersome otherwise.


10. Chris Your Mar 08, 2010 at 08:37

Congratulations on the Railscasts 3-year anniversary! Thanks for continuing to create great Rails examples for our community.

Chris


11. Joseph Silvashy Mar 08, 2010 at 09:37

cheers Ryan! thanks for three years of excellent screencasts!


12. Keith Mar 08, 2010 at 09:57

many thanks Ryan for three years of great railscasts!


13. tankwanghow Mar 08, 2010 at 11:26

Many thanks ryan... Keep it up...


14. iGEL Mar 08, 2010 at 14:03

Santiago: That works in Rails 2.3.5 already. I've used that plugin for a new app already, so it will be easier to migrate to rails 3.


15. Santiago Pastorino Mar 08, 2010 at 14:55

iGEL: I think you didn't understand what I said I was talking about link_to bug and some reported bugs related to xss that are now solved


16. Dom Mar 08, 2010 at 17:56

class Happy::Anniversary < Momentous::Event
  has_many :thanks, :through => :dom
  ...
  has_many :best_wishes, :through => :dom
  ...
  belongs_to :ryan_bates

  private
    def self.message
      "Thank you for being so instrumental in my
       adoption of Ruby and Rails - and please keep
       up the great work. I'm looking forward to
       another 3 years!"
    end
end


17. Martijn Mar 08, 2010 at 23:06

Thanks again, and congrats with your 3rd 'birthday'.

Question: in #136 about jQuery you showed how to escape_javascript().
Does that become obsolete in a silimar way as escaping html with h() in Rails 3?


18. Dennis Fleen Mar 09, 2010 at 03:51

Hey!

Big congrats on your three years of great podcasts! I've followed you from around episode 10 or something, and I'm allway looking forward to your work.

Keep up the good work, it is so much appreciated!


19. Jeff Mar 09, 2010 at 09:09

This highlights something that has always bothered me about the h method in views. I'm glad to see that it's been made default so that it can safely be forgotten, but in my opinion the proper place the sanitize the field is in the model before_save, not in the view. Imagine a post with 100 comments. I can sanitize the fields of all 100 comments every time the view is rendered, or I can sanitize each field once when it's saved. Even if the h method takes a very small fraction of a second, in aggregate sanitizing once in the model should make a notable difference in performance.

I've been meaning to write a benchmark to measure the difference in response time for an app that sanitizes the fields that need sanitizing once versus every time the view is rendered, maybe it's time I finally do it.


20. Brian Armstrong Mar 09, 2010 at 12:14

So why did "foo".html_safe? return false?

This wasn't clear to me. The string didn't contain anything harmful.

Thanks Ryan!


21. VW Mar 09, 2010 at 13:11

@Brian: html_safe? is not determined by looking at the string content, but is set by invoking the html_safe method on the string.


22. Martijn Mar 10, 2010 at 02:02

@Jeff: That's an alternative, but as Rian Bates points out in episode #27, if you put sanitized html into your database, you'll never be able to use it in another way than displaying it again as html. But then again, if that's all you want, I guess it's a good alternative.


23. Martijn Mar 10, 2010 at 02:25

It's Ryan, not Rian of course, sorry for the typo....


24. Doug Hall Mar 10, 2010 at 11:55

Congratulations on three years of excellent screencasts. It's hard to believe that you haven't missed a single week! I can't describe how much help you've been to my career. You've really helped to iron out the wrinkles in Rails. Thank You!, Thank You!, Thank You!, Ryan.


25. inqui Mar 10, 2010 at 14:30

Many ppl do something to help other developers or newcomers, but three years of constant "duty" are outstanding, to say the least.


26. Tobias Mar 14, 2010 at 01:19

Thanks a lot!
We started using this method a while back when the XSS-Plugin for the current rails became avaliable so we wont have to switch to much code.

I have a view more notes:

1. HAML:
I have to use = "some #{code}" from time to time in my template. Since all "" are considert unsave, the easy way to make them safe in HAML is to write != "some #{code}". Unfortunatelly the code-highlighting doesnt support this but it works fine.

2. Helper:
I use the safe_helper-Helpermethod in my helpers to mark them safe globally.
More: http://github.com/nzkoz/rails_xss

3. HTML-Tag-Helper: I am not shure about that but I had problems using html-tag-helper since they mark your html safe without much thinking. Thats not so nice since the whole new escaping makes you feel save and I forgot to look at the html-helper-tags for a while...
(See comment http://rvdh.de/blog/2009/12/14/rails-3-xss-protection-in-erb/#comment-27963694 in german)

4. Btw, where is the difference between .html_safe and .html_safe!
?


27. Ryan Bates Mar 15, 2010 at 09:57

@Santiago, thanks for pointing this out. I took a look at the rails_xss plugin a while back but it was lacking much of the Rails 3 functionality. It looks like that has been resolved so I've updated the show notes for this episode to point this out.

@Jeff, I haven't tested the performance hit of the "h" method, but even with Rails 3 the escaping is happening when rendering the view so the performance may still be an issue in some situations

Caching the sanitized output in the database can get messy and I recommend holding off until you know the HTML escaping is the bottleneck. Also consider other forms of caching such as fragment caching which will likely offer more performance improvements over a database cache.

@Tobias, html_safe returns a new string (actually SafeBuffer) and html_safe! makes the current one safe. If you try "html_safe!" on a string it will not work because only a SafeBuffer can be marked safe.

This was done for performance reasons. See this blog post by Yehuda for details.
http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/


28. terracotta warriors Mar 16, 2010 at 18:22

Caching the sanitized output in the database can get messy and I recommend holding off until you know the HTML escaping is the bottleneck. Also consider other forms of caching such as fragment caching which will likely offer more performance improvements over a database cache.


29. MJ Mar 25, 2010 at 09:18

Great, thanks!


30. Bernhard Apr 14, 2010 at 16:10

Hi Brian! Thanks a lot for the last 3 years. Your work is amazing and keeps me loving rails. You are my Rails Hero #1!


31. Griffin.邱 Jul 14, 2010 at 07:01

hey, thanks your podcasts


32. Griffin.邱 Jul 14, 2010 at 07:03

<script>alert('I stole cookies')</script>


33. <script>alert('I stole cookies')</script> Jul 14, 2010 at 07:04

<script>alert('I stole cookies')</script>


34. samsung ln46c630 Jul 18, 2010 at 01:56

thanks,I download it and have a try first


35. samsung ln40c630 Jul 18, 2010 at 01:58

Thank you for sharing the article .


36. Descargar programas Gratis Jul 19, 2010 at 01:40

Thank you.I hope I can improve through learning this respect. But overall, it's very nice. Thank you for your share!


37. short uggs Jul 21, 2010 at 09:24

great post,i hope you update asap for


38. Send flowers to Korea Jul 25, 2010 at 23:03

Don't know what is wrong what is rite but i know that every one has there own point of view and same goes to this one


41. online advertising Dubai Jul 28, 2010 at 08:03

Resources like the one you mentioned here is very useful! I will post a link to this page on my blog. I am sure my visitors will find that very useful.


41. tiffany Earrings Aug 02, 2010 at 20:14

This wasn't clear to me. The string didn't contain anything harmful.

Thanks Ryan!


42. Tubiletta Aug 06, 2010 at 03:26

Thank's. I am apreciating it very much.


43. rod ends Aug 08, 2010 at 01:48

We manufacture clevis, ball jiont, rod ends, Nb-gj.com has a large number of strong technical staff, to provide customers with quality products.


44. pump shoes Aug 08, 2010 at 22:06

i love <a href=http://www.gavots.com> armani sunglasses </a>very much


46. 3D Glasses Fan Aug 10, 2010 at 06:40

Very well done, thanks alot, I had really been waiting for this one :)


47. UGG Boots on sale Aug 10, 2010 at 18:49

Gooooooooooooooooooood luck ~~!!


48. webcam videooo Aug 11, 2010 at 19:16

thanks Ryan for three years of great railscasts!


49. free directory list Aug 11, 2010 at 22:41

It is marvellous! I like it!


50. UGG Classic Argyle Knit Aug 12, 2010 at 00:15

  The perfect!These articles written too great,they rich contents and data accurately.they are help to me.I expect to see your new share


51. Sesli Chat Aug 12, 2010 at 16:26

Thank You Admin


52. herve leger dress Aug 14, 2010 at 10:29

thank you


53. Rip Blu-ray for Mac Aug 18, 2010 at 01:41

Thanks,it's so good.
suport!


54. Wholesale baseball hats Aug 20, 2010 at 20:10

Good post. I am also going to write a blog post about this...I enjoyed reading your post and I like your take on the issue. Thanks.


55. converse all star Aug 20, 2010 at 20:50

love converse all star,love yourself.High quality low price.It's fit for you.


56. Jordan Air Retro Aug 20, 2010 at 22:47

I am also going to write a blog post about this...I enjoyed reading your post and I like your take on the issue. I really enjoy watching the RailsCasts. I think type of site that is useful in sharing information and it is important to share.


57. Wholesale Electronics Aug 25, 2010 at 00:55

Discount Wholesale Electronics, Wholesale Cell Phones, Electronic Gadgets and More from the Best Dropship Wholesaler


58. sesli chat Aug 26, 2010 at 18:07

sesli sohbet siteleri


59. louis vuitton shoes Aug 26, 2010 at 21:17

Thanks for sharing your article. I really enjoyed it. I put a link to my site to here so other people can read it. My readers have about the same interets


60. LG 32LD350 Aug 28, 2010 at 14:53

Thanks for sharing!


61. herve leger dress Aug 30, 2010 at 19:41

I recently wrote on my blog a post questioning whether or not the GOP is worthy of taking the reins of the House majority from the hated lefties.


62. snow boots Aug 30, 2010 at 20:27

Looks like rails 3 is coming up nicely. I cant wait till its out of beta.


63. winter boots Aug 31, 2010 at 00:49

I am also going to write a blog post about this..


64. new era hats Aug 31, 2010 at 07:47

Best new era caps,new era hats,delicate monster energy hats,magical nfl hats,one industries hats,rockstar energy hats,Red Bull Caps,The Hundreds Hats,Supreme Hats,DC Comics Hats are in stock now. Our site provide first-class service and reliable quanlity garantee,do not hesitate to shake hands with us and go with the tide as soon as possible!


65. louis vuitton sunglasses Sep 01, 2010 at 22:42

There are certainly a lot of details like that to take into consideration. That is a great point to bring up.


66. blu ray ripper Sep 02, 2010 at 00:18

This is really a nice guide for Newbies like me. Thank you.

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player
Give Back to Open Source