websecurity@lists.webappsec.org

The Web Security Mailing List

View all threads

Improved double submit csrf prevention

RH
Richard Hauswald
Thu, Apr 28, 2011 1:08 PM

Hello list,
based on the input I got from many people I created yet another way to
prevent csrf. Here are my thoughts:
0. Create a session wide secret key and a session wide salt

  1. Create a new secure random long enough to avoid conflicts. This
    token will be called Double Submit Token
  2. Set this token in a secure, http-only cookie
  3. Build a HMAC like this: hmac(doubleSubmitToken + sessionWideSalt,
    sessionWideSecretKey) and write this string in a hidden form field or
    HTTP Response Header for ajax requests
  4. When a POST arrives:
    a) fail if  no the cookie value is present
    b) fail if  hmac(cookieValue + sessionWideSalt,
    sessionWideSecretKey) NOT EQUALS (the posted hmac string of the hidden
    form field or HTTP Response Header for ajax requests)
  5. If a POST or a GET arrives:
    a) Create a new secure random long enough to avoid conflicts. This
    token will be called Double Submit Token
    b) Set this token in a secure, http-only cookie
    c) Build a HMAC like this: hmac(doubleSubmitToken +
    sessionWideSalt, sessionWideSecretKey) and write this string in a
    hidden form field or HTTP Response Header for ajax requests

Based on https://www.owasp.org/index.php/HttpOnly I concluded that
setting the same token in a http only cookie and hidden field may not
protect you in case of XSS since not every Browser protects a HTTP
only cookie from being written....

I also noticed that there are many people out there not trusting
cookies. James Manico states that: "I think one token per session is a
reasonable tradeoff for a framework."
IMHO it might be good idea to implement both algorithms so one can use
the combined csrf protection of both methods.

What do you think about this?
Regards,
Richard

--
Richard Hauswald
Blog: http://tnfstacc.blogspot.com/
LinkedIn: http://www.linkedin.com/in/richardhauswald
Xing: http://www.xing.com/profile/Richard_Hauswald

Hello list, based on the input I got from many people I created yet another way to prevent csrf. Here are my thoughts: 0. Create a session wide secret key and a session wide salt 1. Create a new secure random long enough to avoid conflicts. This token will be called Double Submit Token 2. Set this token in a secure, http-only cookie 3. Build a HMAC like this: hmac(doubleSubmitToken + sessionWideSalt, sessionWideSecretKey) and write this string in a hidden form field or HTTP Response Header for ajax requests 4. When a POST arrives: a) fail if no the cookie value is present b) fail if hmac(cookieValue + sessionWideSalt, sessionWideSecretKey) NOT EQUALS (the posted hmac string of the hidden form field or HTTP Response Header for ajax requests) 5. If a POST or a GET arrives: a) Create a new secure random long enough to avoid conflicts. This token will be called Double Submit Token b) Set this token in a secure, http-only cookie c) Build a HMAC like this: hmac(doubleSubmitToken + sessionWideSalt, sessionWideSecretKey) and write this string in a hidden form field or HTTP Response Header for ajax requests Based on https://www.owasp.org/index.php/HttpOnly I concluded that setting the same token in a http only cookie and hidden field may not protect you in case of XSS since not every Browser protects a HTTP only cookie from being written.... I also noticed that there are many people out there not trusting cookies. James Manico states that: "I think one token per session is a reasonable tradeoff for a framework." IMHO it might be good idea to implement both algorithms so one can use the combined csrf protection of both methods. What do you think about this? Regards, Richard -- Richard Hauswald Blog: http://tnfstacc.blogspot.com/ LinkedIn: http://www.linkedin.com/in/richardhauswald Xing: http://www.xing.com/profile/Richard_Hauswald
RP
Rohit Pitke
Fri, Apr 29, 2011 5:25 AM

Hello,

Things seem reasonable. Also, even if you create session-wide double submit
token, instead of creating it for every form, that shall also suffice. I am not
sure what were your thoughts about this.

But one thing I would like to ask is why you would need HMAC for 3 generated
values? Cant it be modified like

  1. Generate random enough session token. Put it as HTTPOnly cookie.
  2. Generate another random token and put it as csrf-token. On server side, tide
    cookie session and csrf-token.
  3. Send both of these values in cookie and query string(for GET)/hidden
    fields(for POST).
  4. Once request gets submitted, validate their presence and then their values.

I know, HMAC provides more robust support for integrity/confidentiality but it
might involve additional operations.

In any case, I am in full concur with your algorithm too.

Thanks,
Rohit


From: Richard Hauswald richard.hauswald@googlemail.com
To: websecurity websecurity@lists.webappsec.org
Sent: Thu, April 28, 2011 6:38:50 PM
Subject: [WEB SECURITY] Improved double submit csrf prevention

Hello list,
based on the input I got from many people I created yet another way to
prevent csrf. Here are my thoughts:
0. Create a session wide secret key and a session wide salt

  1. Create a new secure random long enough to avoid conflicts. This
    token will be called Double Submit Token
  2. Set this token in a secure, http-only cookie
  3. Build a HMAC like this: hmac(doubleSubmitToken + sessionWideSalt,
    sessionWideSecretKey) and write this string in a hidden form field or
    HTTP Response Header for ajax requests
  4. When a POST arrives:
    a) fail if  no the cookie value is present
    b) fail if  hmac(cookieValue + sessionWideSalt,
    sessionWideSecretKey) NOT EQUALS (the posted hmac string of the hidden
    form field or HTTP Response Header for ajax requests)
  5. If a POST or a GET arrives:
    a) Create a new secure random long enough to avoid conflicts. This
    token will be called Double Submit Token
    b) Set this token in a secure, http-only cookie
    c) Build a HMAC like this: hmac(doubleSubmitToken +
    sessionWideSalt, sessionWideSecretKey) and write this string in a
    hidden form field or HTTP Response Header for ajax requests

Based on https://www.owasp.org/index.php/HttpOnly I concluded that
setting the same token in a http only cookie and hidden field may not
protect you in case of XSS since not every Browser protects a HTTP
only cookie from being written....

I also noticed that there are many people out there not trusting
cookies. James Manico states that: "I think one token per session is a
reasonable tradeoff for a framework."
IMHO it might be good idea to implement both algorithms so one can use
the combined csrf protection of both methods.

What do you think about this?
Regards,
Richard

--
Richard Hauswald
Blog: http://tnfstacc.blogspot.com/
LinkedIn: http://www.linkedin.com/in/richardhauswald
Xing: http://www.xing.com/profile/Richard_Hauswald


The Web Security Mailing List

WebSecurity RSS Feed
http://www.webappsec.org/rss/websecurity.rss

Join WASC on LinkedIn http://www.linkedin.com/e/gis/83336/4B20E4374DBA

WASC on Twitter
http://twitter.com/wascupdates

websecurity@lists.webappsec.org
http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org

Hello, Things seem reasonable. Also, even if you create session-wide double submit token, instead of creating it for every form, that shall also suffice. I am not sure what were your thoughts about this. But one thing I would like to ask is why you would need HMAC for 3 generated values? Cant it be modified like 1. Generate random enough session token. Put it as HTTPOnly cookie. 2. Generate another random token and put it as csrf-token. On server side, tide cookie session and csrf-token. 3. Send both of these values in cookie and query string(for GET)/hidden fields(for POST). 4. Once request gets submitted, validate their presence and then their values. I know, HMAC provides more robust support for integrity/confidentiality but it might involve additional operations. In any case, I am in full concur with your algorithm too. Thanks, Rohit ________________________________ From: Richard Hauswald <richard.hauswald@googlemail.com> To: websecurity <websecurity@lists.webappsec.org> Sent: Thu, April 28, 2011 6:38:50 PM Subject: [WEB SECURITY] Improved double submit csrf prevention Hello list, based on the input I got from many people I created yet another way to prevent csrf. Here are my thoughts: 0. Create a session wide secret key and a session wide salt 1. Create a new secure random long enough to avoid conflicts. This token will be called Double Submit Token 2. Set this token in a secure, http-only cookie 3. Build a HMAC like this: hmac(doubleSubmitToken + sessionWideSalt, sessionWideSecretKey) and write this string in a hidden form field or HTTP Response Header for ajax requests 4. When a POST arrives: a) fail if no the cookie value is present b) fail if hmac(cookieValue + sessionWideSalt, sessionWideSecretKey) NOT EQUALS (the posted hmac string of the hidden form field or HTTP Response Header for ajax requests) 5. If a POST or a GET arrives: a) Create a new secure random long enough to avoid conflicts. This token will be called Double Submit Token b) Set this token in a secure, http-only cookie c) Build a HMAC like this: hmac(doubleSubmitToken + sessionWideSalt, sessionWideSecretKey) and write this string in a hidden form field or HTTP Response Header for ajax requests Based on https://www.owasp.org/index.php/HttpOnly I concluded that setting the same token in a http only cookie and hidden field may not protect you in case of XSS since not every Browser protects a HTTP only cookie from being written.... I also noticed that there are many people out there not trusting cookies. James Manico states that: "I think one token per session is a reasonable tradeoff for a framework." IMHO it might be good idea to implement both algorithms so one can use the combined csrf protection of both methods. What do you think about this? Regards, Richard -- Richard Hauswald Blog: http://tnfstacc.blogspot.com/ LinkedIn: http://www.linkedin.com/in/richardhauswald Xing: http://www.xing.com/profile/Richard_Hauswald _______________________________________________ The Web Security Mailing List WebSecurity RSS Feed http://www.webappsec.org/rss/websecurity.rss Join WASC on LinkedIn http://www.linkedin.com/e/gis/83336/4B20E4374DBA WASC on Twitter http://twitter.com/wascupdates websecurity@lists.webappsec.org http://lists.webappsec.org/mailman/listinfo/websecurity_lists.webappsec.org
JM
James Manico
Fri, Apr 29, 2011 3:03 PM

James Manico states that: "I think one token per session is a reasonable

tradeoff for a framework

Let me clarify. I'd rather see one CSRF token per request but such a feature
is more complex to implement and tends to break stuff. For a framework (like
struts) I think one CSRF token per session is a reasonable design decision.
Even better, support both (at the framework level again) and let the dev
configure which one is active.

Jim Manico

On Apr 28, 2011, at 7:48 AM, Richard Hauswald <
richard.hauswald@googlemail.com> wrote:

James Manico states that: "I think one token per session is a
reasonable tradeoff for a framework

> James Manico states that: "I think one token per session is a reasonable tradeoff for a framework Let me clarify. I'd rather see one CSRF token per request but such a feature is more complex to implement and tends to break stuff. For a framework (like struts) I think one CSRF token per session is a reasonable design decision. Even better, support both (at the framework level again) and let the dev configure which one is active. Jim Manico On Apr 28, 2011, at 7:48 AM, Richard Hauswald < richard.hauswald@googlemail.com> wrote: James Manico states that: "I think one token per session is a reasonable tradeoff for a framework
T
Tim
Mon, May 2, 2011 12:07 AM

Hi Richard,

I think you might be making it more complicated than it needs to be.
The algorithm I had proposed previously does not require any use of
cookies (HMAC values passed only in POST body, URL parameters, or
custom HTTP headers) and every single request would have a separate
HMAC value.  The HMAC values would all remain valid in multithreaded
scenarios (e.g. asynchronous AJAX) for a configurable period of time,
but are tied to the session so would expire with it.  It also happens
to be far simpler than what you propose.

What is it you are trying to accomplish beyond those
features/protections?

To be clear about XSS implications, these methods can help one prevent
exploitation of reflected XSS because injection attempts should be
outright rejected before injection can occur, but once client-side
script is successfully injected (perhaps via stored XSS or other
scenarios), these tokens of course provide no protection.

tim

Hi Richard, I think you might be making it more complicated than it needs to be. The algorithm I had proposed previously does not require any use of cookies (HMAC values passed only in POST body, URL parameters, or custom HTTP headers) and every single request would have a separate HMAC value. The HMAC values would all remain valid in multithreaded scenarios (e.g. asynchronous AJAX) for a configurable period of time, but are tied to the session so would expire with it. It also happens to be far simpler than what you propose. What is it you are trying to accomplish beyond those features/protections? To be clear about XSS implications, these methods can help one prevent exploitation of reflected XSS because injection attempts should be outright rejected before injection can occur, but once client-side script is successfully injected (perhaps via stored XSS or other scenarios), these tokens of course provide no protection. tim