I really like the idea of acts_as_secure/unescaped, especially with the method missing catch as you have mentioned.
<%= model.name_raw %> or <%= model.name %> Raw is simply a naming preference for me, as name would be the processed version (secured). The discussions so far have shown two very strong sides of opinions towards the idea of having xss (or even security in general) enabled by default, yet one point still stands in merit alone. Rails should be secure by default. PHP has been plagued with never ending hacks on applications built the language due to the precise reason of it's default ability for programmers to choose to secure their applications, rather than the reverse, which we are discussing to purposefully choose to turn off the security in the framework. For a second, imagine Rails as a framework you have to choose to turn off the security. Personally, that sounds like an excellent goal in of itself worth striving for. My initial email I sent with this intent in mind, has struck a nerve, which seems to be tugged back and forth on semantics and may even be dismissed by some and definitely disputed by others solely on the analysis of the finer details. Realizing my goal now, it wasn't to say "this is how it should be done", but rather, "how about we solve the issue of security before it becomes a problem". The recommendation towards having <%= output the same content as <%=h seems to have addressed a very important point, that security should be enabled default. Backwards compatibility is obviously going to be a serious point to enable something like this. A few methods of solving this that were suggested: 1. Have a option in config/environment.rb that enables security be default, or even the level/degree of security you want. Similar to PHP's error output level. 2. Create a new plugin such as acts_as_unescaped for each of the data types with the ability to have method_missing catches so you can access the model.name_raw value. 3. Modify ERB to create a new output stream which is secure <%~ The third point, where by the recommendation suggested to change ERB and support a new style of <%~, instead of <%= would simply break the intent of my original goal, but is worth still investigating in it's own right. Reason being, you would have to go out of your way again to secure your sprint. The default is <%= now, people are used to it, it has become the standard, which should be enhanced to be the standard which is secure. Your application should be secure by default, and you choose to print the unsecure version with such a statement as <%~ model.name %>, to output the same thing as <%= model.name_raw %>. To summarize Kevin point, the importance of security should not be measured by the loss of performance, but rather the peace of mind gained knowing invested knowledge has been converged to make developing on the path of majority, is safer than treading off on your own. At this point, it is actually safer to go against the default print statement being <%=. I read over and over again, key contributors to the community pairing "PHP" with the security (or lack there of). You only need to look at an application like phpBB to see such evidence. This isn't due to the fact that PHP can't be secured, it simply takes extra resources to really understand and realize that certain methods of doing things are not safe, such as how to avoid SQL injection. To be honest, it took me up until about a few weeks ago to come across a posting from someone in the Rails community why <%=h is needed to secure the output of the user input. I have been developing with rails for some time now, and I know a few things about XSS, yet still, while I was shifting my paradigm to Rails, I had simply forgot about encoding my HTML output. The apps I have written are not blogware, or open to the public so this wasn't a major concern of mine, but it brought up a good point. At what point do we say, OK, I need to secure my application now. Another example to highlight is the :conditions on things such as model.find. This should always be encoded, and you should have to override the default to allow direct data insertion. That said, when finding all records such as this: Model.find(:all, :conditions => 'this = "' + params[:xss] + '"') Should not even be allowed to happen. One method I had found, maybe a month after getting into Rails, was a post by Robby mentioning how to use hash marks, like so: Model.find(:all, :conditions => ['this = :this', {:this => params[:xss]}]) Now, from what I gather that is the secure way of writing a condition, yet TONS of people I can guarantee have no idea about this, or even the simpler method without the named using the sprintf method. Either way, security should be default, and you should have to break off the Rails path to choose to open up security holes in your application. - Nb ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Nathaniel S. H. Brown http://nshb.net ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > -----Original Message----- > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] On Behalf > Of Kevin Olbrich > Sent: February 14, 2006 8:44 PM > To: rails-core@lists.rubyonrails.org > Subject: Re: [Rails-core] Default <%= to use the h (html safe) method. > > There was a discussion about this on the main rails list a > week or two ago... > > Basic conclusions that I cam away with were... > > Since most of the problematic data would be coming from the > database, it might be easiest to set up activerecord to > escape text by default. This escaping could be turned off in > the model definition if necessary. > > class Model < AR::Base > acts_as_unescaped :attribute1, :attribute2 end > > method_missing could also be set up to recognize things like > "#{attribute}_unsafe" to return the unescaped code. This has > the bonus effect of self documenting the code and making it > obvious when the unescaped value is being used. > > For example, which code fragment below is returning unescaped text? > > <%= item.name_unsafe %> > > or > > <%= item.name %> > > Changing ERb will probably lead to enormous headaches at this point. > > The key thing is to change the default behavior to secure > rather than unsecure. If you fail to unescape when the > default in secure, you just break the app. If you fail to > escape when the default is unsecure, you expose your data. > > A broken app will be obvious from your tests and can be > fixed, an unsecure one probably won't, and you won't know > there is a problem until its too late. > > Sure it will impose a performance hit, but this should really > be a secondary concern to security. > > _Kevin > > -- > Posted with http://DevLists.com. Sign up and save your time! > _______________________________________________ > Rails-core mailing list > Rails-core@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails-core > _______________________________________________ Rails-core mailing list Rails-core@lists.rubyonrails.org http://lists.rubyonrails.org/mailman/listinfo/rails-core