tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Violeta Georgieva <violet...@apache.org>
Subject Re: CsrfPreventionFilter for REST
Date Wed, 26 Sep 2012 05:27:11 GMT
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 <violetagg@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
>
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message