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

Reply via email to