March 10, 2016 at 10:00 pm #8495
I need to implement CSRF protection for my applications. As we are using OpenIG as a gateway I thought OpenIG could be in charge to:
1. Create the CRSF token and set it as a cookie in the response if the CRSF token does not exists – I guess it could be stored in the OpenIG context
2. Obtain the CRSF token from incoming requests (which name would be different to the cookie set in the response as explained in 1 and compare it to the one stored in the OpenIG context (connected to the user session).
At the end of the day, several applications will use the OpenIG gateway so I thought is a good place to implement CSRF protection.
My questions are:
– Is this a good approach? are there any other better ways to implement CRSF with OpenIG?
– Is there any out-of-the-box filter / handler / feature helping to implement this?
– If there is nothing, could this be implemented using the ScriptableFilter?
Thanks so much, any help will be appreciated!
March 16, 2016 at 3:57 pm #8602Guillaume SauthierModerator
- This topic was modified 6 years, 5 months ago by Miguel F.
Well, usual CSRF protection technics involve a transfer of some secret (the token) from the application to the user-agent and then the user-agent is responsible to add back this secret in requests (usually
Traditionally, this is a hidden
<input ...>in forms, or sometime, the addition of a
If we imagine to do the same with a transparent reverse-proxy (means that the app doesn’t know about CSRF), that would mean that the response’s content should be enriched with the token, and this is not a trivial task to do in a generic fashion.
Your proposition is slightly different: the token would be passed to the UA using a cookie, but then the UA has to send back the token when doing requests. If we assume it will come back with the cookie, then there is not such much protection, because an illegal request would have the cookie, just like other requests.
So the token has to be explicitly added by the UA for each form submition. And then we come back to the content rewriting/enriching issue: the HTML is build on the protected application, there is still no hidden
So, to finish on a more positive note: we can still do something with OpenIG :)
If we consider the case of a not so transparent reverse-proxy, we could imagine that IG would be responsible of token generation, it could look for marker in the HTML (the hidden
<input ...>field) and then substitute the marker with the actual token. When a
POSTrequest comes in, it would check the presence of the token in form parameters.
Note that this solution ties your application(s) to OpenIG: they are still responsible of generating a CSRF-aware HTML:
<form ...> // ... <input type="hidden" value="#CSRF_TOKEN#" /> </form>March 16, 2016 at 5:22 pm #8607
Thanks so much for your answer.
The client side would be AngularJS single page apps. There is already support from AngularJS to handle XSRF from the client side. The client side app gets a cookie with name “XSRF-TOKEN” (by default) from the server response and needs to add it in every request as a header with name “X-XSRF-TOKEN” (by default – obviously this header has a different name from the cookie so it’s set by the application and not propagated automatically by the browser). AngularJS takes care of this, so the ‘client side’ is already covered.
OpenIG would be in charge of the ‘server side’ XSRF responsibilities (1. token generation and 2. token validation).
It would generate the token with name “XSRF-TOKEN” and adding it to the respose in the “login” request (the first request) and it will store it in the context of the logged in user. For the rest of requests it will always check that a header called “X-XSRF-TOKEN” comes in the request and the value matches the value stored in the user context. Otherwise it would return 401 or 403 (Not authorized or Forbidden).
At the end of the day we want to protect apps that rely on cookies for security so an attacker can’t take advantage of the session of a user that is logged in to trick him / her to make requests to the server side that will be accepted as valid (as the cookies are propagated by the browser automatically, for instance “iPlanetDirectoryPro” and some custom cookies).
In summary for applications using OpenIG as gateway to the service layer, I guess the own gateway is a good point to implement the CSRF server side protection code.
In fact, if the name of the XSRF cookie and XSRF header can be configurable, this OpenIG CSRFFilter can be a general purpose one and it could be even contributed to OpenIG.
Does it make sense?
Thanks for your help
Annex: About AngularJS Support (from ): https://docs.angularjs.org/api/ng/service/$http
Cross Site Request Forgery (XSRF) Protection
The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName properties of either $httpProvider.defaults at config-time, $http.defaults at run-time, or the per-request config object.
In order to prevent collisions in environments where multiple Angular apps share the same domain or subdomain, we recommend that each application uses unique cookie name.
March 17, 2016 at 8:30 am #8629Guillaume SauthierModerator
- This reply was modified 6 years, 4 months ago by Miguel F.
If you app already have support for CSRF protection, then doing the cookie stuff and verification on IG make sense.
Do you know if other JS based frameworks are using the same CSRF protection technic ? If there are some, then this filter is not tight to AngularJS.
That would be a great contribution!
Please keep us posted of your progress and come back here if you need any helpMarch 17, 2016 at 8:52 am #8635
Yes, it is common to implement CSRF protection using a cookie (set cookie from ‘server side’) and a header (different name from the cookie) from the ‘client side’.
Spring framework for instance uses this same approach both for the server side support it provides and client side (for the technologies with Spring CSRF support, JSP, Thymeleaf, etc..).
If fact an improvement is that the server side looks for the CSRF token both in a header or in an attribute so you have two ways of passing the token depending on the client. This would work for client solutions as you describe where they need to add the CSRF token as a field of a form.
So this is a good candidate to be a new general purpose CSRF OpenIG filter. With a bit of polishing and allowing configuration (name of the header / attribute, cookie, only accept header or attribute / both, etc..) it can provide the server side solution to fit with different clients.
Ok. Thanks for confirming that this seems a good idea.
We will try to implement this and I’ll keep you posted. We might share it with you and you might need to polish / refactor a bit as i’m quite new to OpenIG and I’ll be probably a bit ‘awkward’ with OpenIG expressions and programming :-)
- This reply was modified 6 years, 4 months ago by Miguel F.
You must be logged in to reply to this topic.