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.
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.
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!
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
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.
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.
@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.
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.
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!
?
@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/
Warning: link_to method is NOT safe because its not properly encoding all characters into percent-encoding (skipping slash)
In your video if you click on the link with "...</strong>" text your application woulnt probably work because the slash in this string would brake your routing rules.
Actually this is not an XSS safety but an attacker could provide a string that would break the app from working (broken links).
I have no idea why link_to encodes only few characters and not all according to the specs.
Awesome thanks again! We need screencast on mongodb and rails 3!
Brilliant, thanks for all your efforts with the weekly railscasts.
@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
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.
Thanks Ryan, I am really loving this series of screencasts dedicated to the new rails 3 features.
Wow. Well done!
Thank you very much.
Ben
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
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
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.
Congratulations on the Railscasts 3-year anniversary! Thanks for continuing to create great Rails examples for our community.
Chris
cheers Ryan! thanks for three years of excellent screencasts!
many thanks Ryan for three years of great railscasts!
Many thanks ryan... Keep it up...
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.
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
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
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?
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!
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.
So why did "foo".html_safe? return false?
This wasn't clear to me. The string didn't contain anything harmful.
Thanks Ryan!
@Brian: html_safe? is not determined by looking at the string content, but is set by invoking the html_safe method on the string.
@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.
It's Ryan, not Rian of course, sorry for the typo....
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.
Many ppl do something to help other developers or newcomers, but three years of constant "duty" are outstanding, to say the least.
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!
?
@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/
Great, thanks!
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!
Warning: link_to method is NOT safe because its not properly encoding all characters into percent-encoding (skipping slash)
In your video if you click on the link with "...</strong>" text your application woulnt probably work because the slash in this string would brake your routing rules.
Actually this is not an XSS safety but an attacker could provide a string that would break the app from working (broken links).
I have no idea why link_to encodes only few characters and not all according to the specs.
there is always (at the very least) a small thing to learn or to remember to be aware of, even in the old well known episodes. - thanks