# Cross site scripting security

**URL:** <https://www.ruby-forum.com/t/cross-site-scripting-security/163998>\
**Category:** Rails\
**Created:** [March 26, 2009, 6:51pm UTC](https://www.ruby-forum.com/t/cross-site-scripting-security/163998 "2009-03-26T18:51:07Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [March 26, 2009, 6:51pm UTC](https://www.ruby-forum.com/t/cross-site-scripting-security/163998/1 "2009-03-26T18:51:07Z")

</div>

I just changed my session store to use active record because it  
appears session expiration and so on may be easier that way and it  
seems like a better option.

In my base controller I have:

protect\_from\_forgery :secret =\> ‘hgfjh…kjhghglh’ (whatever)

self.allow\_forgery\_protection = false

I had commented those out during development because certain actions  
would error out because of these.  
For instance, I think I called remote\_function() from java script and  
just added :width=\>something.  
That added width into params, but I guess since it wasn’t part of the  
routing the forgery protection  
flagged an error on it, is my guess.

Is the best way to go through and try to fix the routing for  
everything ? I guess that might be the way I have to do it, I wanted  
to check if I really need to do that for security as it’s sort of a  
pain in the neck to have to try to test  
all the methods, fix the routing and such …

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [March 26, 2009, 8:45pm UTC](https://www.ruby-forum.com/t/cross-site-scripting-security/163998/2 "2009-03-26T20:45:47Z")

</div>

removed\_email\_address@domain.invalid wrote:

> protect\_from\_forgery :secret =\> ‘hgfjh…kjhghglh’ (whatever)
> 
> self.allow\_forgery\_protection = false
> 
> I had commented those out during development because certain actions  
> would error out because of these.

If you’re concerned about security then commenting that out to resolve  
the errors you were getting in development was probably a mistake.

> For instance, I think I called remote\_function() from java script and  
> just added :width=\>something.  
> That added width into params, but I guess since it wasn’t part of the  
> routing the forgery protection  
> flagged an error on it, is my guess.
> 
> Is the best way to go through and try to fix the routing for  
> everything ? I guess that might be the way I have to do it, I wanted  
> to check if I really need to do that for security as it’s sort of a  
> pain in the neck to have to try to test  
> all the methods, fix the routing and such …

Also note that your subject line says Cross Site Scripting (XSS), which  
is not the same as Cross Site Request Forgery (CSRF). The method  
protect\_from\_forgery does nothing (as far as I understand it) to protect  
against XSS. It only provides protection against CSRF.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [March 26, 2009, 9:36pm UTC](https://www.ruby-forum.com/t/cross-site-scripting-security/163998/3 "2009-03-26T21:36:57Z")

</div>

> If you’re concerned about security then commenting that out to resolve  
> the errors you were getting in development was probably a mistake.

Right, well I had this funny feeling about it, but at the time I was  
trying to get some javascript stuff to work …

Anyway, there is a javascript call like this:

function update\_server(info)  
{

\<%= remote\_function(:url =\> {:action =\> ‘resize\_field’},  
:with =\> ‘{col:info.col,width:info.width}’)  
%\>  
}

So I just set some routing, I’m not a routing expert, but I did this:

map.connect ‘shgrid/resize\_field/:col/:width’,  
:controller =\> ‘shgrid’,  
:action =\> ‘resize\_field’

But I get the error (below). I’m not sure if there’s a proper way to  
do it with remote\_function() ?  
Anyway, first I did the main dev, now I am trying to learn more on  
security …

Processing ShgridController#resize\_field (for 155.x.x.x at 2009-03-26  
16:28:11) [POST]  
Session ID: 92c3ef636f552fbeff8e574d96bedb9f  
Parameters: {“col”=\>“5”, “action”=\>“resize\_field”,  
“controller”=\>“shgrid”, “width”=\>“66”}  
User Load (0.000269) SELECT \* FROM “users” WHERE (name = ‘Zack2’)  
LIMIT 1  
AdminSetting Load (0.000156) SELECT \* FROM “admin\_settings” LIMIT  
1

ActionController::InvalidAuthenticityToken  
(ActionController::InvalidAuthenticityToken):  
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.1.2/lib/  
action\_controller/request\_forgery\_protection.rb:86:in  
`verify_authenticity_token' /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.1.2/lib/ active_support/callbacks.rb:173:in`send’  
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.1.2/lib/  
active\_support/callbacks.rb:173:in `evaluate\_method’

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [March 26, 2009, 9:58pm UTC](https://www.ruby-forum.com/t/cross-site-scripting-security/163998/4 "2009-03-26T21:58:39Z")

</div>

Thanks,

I’m still learning here, but what happens is if I copy the token from  
some other action that works so I now have this:

\<%= remote\_function(:url =\> {:action =\> ‘resize\_field’,  
:authenticity\_token  
=\>“sda4354326hfghgfsf-whatever”},  
:with =\> ‘{col:info.col,width:info.width}’)  
%\>

then the :with part of the clause does not get into the parameters it  
seems like …

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [March 26, 2009, 9:46pm UTC](https://www.ruby-forum.com/t/cross-site-scripting-security/163998/5 "2009-03-26T21:46:43Z")

</div>

Larz wrote:

> But I get the error (below). I’m not sure if there’s a proper way to  
> do it with remote\_function() ?  
> Anyway, first I did the main dev, now I am trying to learn more on  
> security …
> 
> Processing ShgridController#resize\_field (for 155.x.x.x at 2009-03-26  
> 16:28:11) [POST]  
> Session ID: 92c3ef636f552fbeff8e574d96bedb9f  
> Parameters: {“col”=\>“5”, “action”=\>“resize\_field”,  
> “controller”=\>“shgrid”, “width”=\>“66”}  
> User Load (0.000269) SELECT \* FROM “users” WHERE (name = ‘Zack2’)  
> LIMIT 1  
> AdminSetting Load (0.000156) SELECT \* FROM “admin\_settings” LIMIT  
> 1
> 
> ActionController::InvalidAuthenticityToken  
> (ActionController::InvalidAuthenticityToken):  
> /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.1.2/lib/  
> action\_controller/request\_forgery\_protection.rb:86:in  
> `verify_authenticity_token' /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.1.2/lib/ active_support/callbacks.rb:173:in`send’  
> /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.1.2/lib/  
> active\_support/callbacks.rb:173:in `evaluate\_method’

Sure it will fail on that because there is no authenticity token in your  
params:

Example:

Processing ThingsController#create (for 127.0.0.1 at 2009-03-26  
16:42:40) [POST]  
Parameters: {“commit”=\>“Create”,  
“authenticity\_token”=\>“wM7T6k++1upx4BO+fVy571jwqx0d4z0U92PPSGP+UUQ=”,  
“thing”=\>{“name”=\>“Widget”}}

You may just want to disable forgery protection for this one action, but  
use it for all others. There might be a better solution than that, but  
it should get you past this problem.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [March 26, 2009, 10:04pm UTC](https://www.ruby-forum.com/t/cross-site-scripting-security/163998/6 "2009-03-26T22:04:30Z")

</div>

On Thu, Mar 26, 2009 at 3:58 PM, Larz [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’m still learning here, but what happens is if I copy the token from  
> some other action that works so I now have this:
> 
> \<%= remote\_function(:url =\> {:action =\> ‘resize\_field’,  
> :authenticity\_token  
> =\>“sda4354326hfghgfsf-whatever”},

To make it dynamic, I would use form\_authenticity\_token, not the  
actual value of it.

> **[ActionController::RequestForgeryProtection](https://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html#M000491)**
>
> Controller actions are protected from Cross-Site Request Forgery (CSRF) attacks by including a token in the rendered HTML for your application.

–  
Greg D.  
[http://destiney.com/](http://destiney.com/)

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [March 26, 2009, 10:34pm UTC](https://www.ruby-forum.com/t/cross-site-scripting-security/163998/7 "2009-03-26T22:34:27Z")

</div>

> To make it dynamic, I would use form\_authenticity\_token, not the  
> actual value of it.

Thanks,

So I make the call like this, it works fine except I’m not sure why  
the stuff in the :with part from javascript  
doesn’t make it into params when I have authenticity\_token in  
the :url part:

\<%= remote\_function(:url =\> {:action =\> ‘resize\_field’,  
:authenticity\_token =\>  
form\_authenticity\_token,  
},  
:with =\>  
‘{col:info.col,width:info.width}’)  
%\>

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [March 26, 2009, 11:02pm UTC](https://www.ruby-forum.com/t/cross-site-scripting-security/163998/8 "2009-03-26T23:02:36Z")

</div>

The other thing seems to be that if this is set in the base  
controller:  
protect\_from\_forgery :secret =\> ‘10aedsfsdafdasfasdfxvcxvhg’

Then it generates the authenticity tokens, regardless of whether the  
check is made. That seems to break my remote\_function call as  
mentioned in the previous post (because the :with js stuff doesn’t get  
put into the url/ params.

since protect\_from\_forgery I guess it’s called at the class level, I’m  
not sure I can disable it for one action and have it turned on for  
others …

I can turn this off at the instance level:  
self.allow\_forgery\_protection  
but that doesn’t fix my other problem …

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [March 27, 2009, 6:56pm UTC](https://www.ruby-forum.com/t/cross-site-scripting-security/163998/9 "2009-03-27T18:56:12Z")

</div>

Here is where I am at with this so far …

I decied to try to change my code to be all javascript to get around  
the strange problem I was having, so I followed the  
advice from this site:

> **[Rails Forgery Protection (CSRF) and Ajax](http://david-burger.blogspot.com/2008/01/rails-forgery-protection-csrf-and-ajax.html)**
>
> Rails 2.0 has forgery protection against CSRF attacks built in. If you stick to standard rails helpers you won't need to take any extra st...

Here is what my code looks like now which seems to work. I think I am  
using jquery at this point. I’ve commented out the old code:

function update\_server(info)  
{

\<%#= remote\_function(:url =\> {:action =\> ‘resize\_field’},  
:with =\>  
‘{col:info.col,width:info.width}’)  
%\>  
$.ajax({data:  
{col:info.col,width:info.width,authenticity\_token:FORM\_AUTH\_TOKEN},  
dataType:‘script’, type:‘post’, url:‘/shgrid/resize\_field’})

}
