Hi, Did you have a chance to check the issue and the proposal? Can I provide more information in order to make to them clearer?
Thanks a lot. Violeta 2012/9/21 Violeta Georgieva <violet...@apache.org> > Hello,**** > > ** ** > > *Background information:* > > We are trying to protect our RESTful > APIs<http://en.wikipedia.org/wiki/Representational_state_transfer> from > CSRF attack.**** > > The current Tomcat’s CSRF protection filter provides proper protection for > web resources that are supposed to be accessed via some sort of navigation > i.e. there’s an entry point which points to them (for example include > links/post forms to them) . With REST APIs you do not have such entry > points as the requests are done independently from each other. We are > interested do you consider supporting CSRF protection for RESTful APIs?** > ** > > ** ** > > *Example attack:* > > Here is an example how to reproduce CSRF attack of RESTful APIs using the > attached apps:**** > > > 1. Check customers initial state: > http://localhost:8080/restDemo/services/customers/ + login with > tomcat/tomcat > 2. **In the same browser open attacker’s app: > http://localhost:8080/XSRFAttackerApp/ > > ** > > Behind the scenes request 2. takes advantage of your credentials stored in > the browser and makes attacking POST request to a state changing operation > http://localhost:8080/restDemo/services/customers/removeFirst on your > behalf. After that the customer list is empty.**** > > ** ** > > The problem is that if we use the CSRF filter to protect this API > /services/customers/removeFirst, this URL is then always served with *403 > Forbidden* (due to the missing csrf token). In fact the REST API > becomes unusable.**** > > ** ** > > *Research:* > > We’ve made some research on the topic and it seems that there is no > absolutely secure and at the same time clear stateless solution. Since it > is possible for an attacker to insert custom headers in the attacking > requests, the validation over header presence is not secure enough.**** > > The only stable solution is again based on Synchronizer Token > Pattern<https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet> > but > instead of encoded in URLs, the csrf token value can be transferred from > and to the client through a custom csrf token header. The rest csrf token > value needs to be stored in some sort of state on client and server side. > In addition REST clients need to adopt this csrf token transfer mechanism. > **** > > *Proposal:* > > You can find on the link > https://docs.google.com/open?id=0B-HUwAvkRIKJTVViWUFkNFl6alU , the > CsrfPreventionFilter extended so that it is able to successfully protect > state changing REST requests. They are validated based on the > “X-CSRF-Token” header (the header name is configurable). > > * > * > > *Here are some details about the new protection mechanism:* > > > 1. How to recognize REST from non REST requests so that they can be > validated separately - based on different tokens? - There is no clear > way to recognize them, that’s why application developers should point all > rest API URLs in the application through a new filter init parameter named > *restApis*. > 2. How the valid client gets to know the valid CSRF Token? - In order > a REST client (e.g. adapted HTTP client) to obtain a valid CSRF token and > use it for its REST requests it should make an initial non modifying > request (GET, HEAD, OPTIONS) to the application. This request should > contain ‘*X-CRF-Token: Fetch’ *header*. *On such request, the filter > generates and stores a rest csrf token as a session attribute and returns > it together with the jsessionid to the client. > 3. The Client should send the pair j*sessionid* and * csrf token* > header* *whenever it makes modifying REST requests to this > application (POST, PUT, DELETE etc.). > 4. How are invalid state changing requests handled? - They are > responded with HTTP/1.1 403 Forbidden + ‘X-CSRF-Token: Required’ header. > > > > Below you can find example request response process flow. It is based on > the example app - restDemo (also available on the link with the extended > filter).**** > > To try it yourself: apply the patch, remove the commented CSRF protection > configuration in restDemo’s web.xml and deploy. > * > > 1.**Client Request 1:** > *GET /restDemo/services/customers/ HTTP/1.1 > X-CSRF-Token: Fetch > Authorization: Basic dG9tY2F0OnRvbWNhdA== > Host: localhost:8080 > * > * > *Server Response1:* > HTTP/1.1 200 OK > Server: Apache-Coyote/1.1 > Cache-Control: private > Expires: Thu, 01 Jan 1970 03:00:00 EET > *Set-Cookie: JSESSIONID=4BA3D75B73B8C4591F1D915BA9C2B660; > Path=/restDemo/; HttpOnly* > *X-CSRF-Token: 5A44B387B75E54417F6C64FF3D485141* > Content-Type: application/xml > Content-Length: 170 > Date: Fri, 21 Sep 2012 17:53:02 GMT > * > * > *2. ****Client Request 2:* > POST /restDemo/services/customers/removeFirst HTTP/1.1 > *Cookie: JSESSIONID=4BA3D75B73B8C4591F1D915BA9C2B660* > *X-CSRF-Token: 5A44B387B75E54417F6C64FF3D485141* > Authorization: Basic dG9tY2F0OnRvbWNhdA== > Host: localhost:8080 > * > * > *Server Response2:* > HTTP/1.1 200 OK > Server: Apache-Coyote/1.1 > *Set-Cookie: JSESSIONID=03D21FD4498B1446F12A3796441E2598; > Path=/restDemo/; HttpOnly -> sessionid is rechanged after > reauthentication (this is not related to our proposal but the client needs > to track such session changes)* > Content-Type: text/html > Transfer-Encoding: chunked > Date: Fri, 21 Sep 2012 17:53:47 GMT > * > * > *3. ****Client Request 3:* > POST /restDemo/services/customers/removeFirst HTTP/1.1 > *Cookie: JSESSIONID=03D21FD4498B1446F12A3796441E2598* > *X-CSRF-Token: 5A44B387B75E54417F6C64FF3D485141* > Authorization: Basic dG9tY2F0OnRvbWNhdA== > Host: localhost:8080 > * > * > *Server Response3:* > HTTP/1.1 200 OK > Server: Apache-Coyote/1.1 > Content-Type: text/html > Transfer-Encoding: chunked > Date: Fri, 21 Sep 2012 17:59:56 GMT > * > * > *4. Client Requests 4 (negative case 1 ):* > POST /restDemo/services/customers/removeFirst HTTP/1.1 > Cookie: JSESSIONID=03D21FD4498B1446F12A3796441E2598 > Authorization: Basic dG9tY2F0OnRvbWNhdA== > Host: localhost:8080 > * > * > *5. ****Client Requests 5 (negative case 2):* > POST /restDemo/services/customers/removeFirst HTTP/1.1 > Cookie: JSESSIONID=03D21FD4498B1446F12A3796441E2598 > *X-CSRF-Token: fetch* > Authorization: Basic dG9tY2F0OnRvbWNhdA== > Host: localhost:8080 > * > * > *6. ****Client Requests 6 (negative case 3):* > POST /restDemo/services/customers/removeFirst HTTP/1.1 > Cookie: JSESSIONID=03D21FD4498B1446F12A3796441E2598 > *X-CSRF-Token: invalid* > Authorization: Basic dG9tY2F0OnRvbWNhdA== > Host: localhost:8080 > > Requests [4 – 6] are all responded with: > * > * > *Server Response (negative cases 1-3)* > *HTTP/1.1 403 Forbidden* > Server: Apache-Coyote/1.1 > *X-CSRF-Token: Required* > Content-Type: text/html;charset=utf-8 > Content-Length: 961 > Date: Fri, 21 Sep 2012 18:03:16 GMT > > > We are looking forward to your comments. > Best Regards > Violeta and Polina > > >