MP-JWT cookies, CSRF

138 views
Skip to first unread message

Scott Stark

unread,
Mar 27, 2018, 8:44:19 PM3/27/18
to Eclipse MicroProfile
For the Define a standard Cookie for holding the MP-JWT token issue, defining a name (say MP-JWT-TOKEN) and format(just the x.y.z RS256 signed JWT base64 string) for the cookie is strait-forward, but it seems like we also need to enable some consistent configuration and behavior for CSRF/XSRF protection. If enabled, the MP-JWT service would need to include a XSRF-TOKEN cookie that contains a random string in addition to the MP-JWT-TOKEN, and validate the X-XSRF-TOKEN header to ensure it contains the XSRF-TOKEN cookie value last returned to the client.

Additional configuration settings for marking the MP-JWT-TOKEN as HttpOnly and Secure are probably also needed.

Feedback?


Scott Stark

unread,
Mar 27, 2018, 10:13:31 PM3/27/18
to Eclipse MicroProfile

Alasdair Nottingham

unread,
Mar 28, 2018, 1:00:02 PM3/28/18
to 'Emily Jiang' via Eclipse MicroProfile
I would have hoped that the http only and secure flags would be set by default and we could get away with not allowing them to be changed. I’ve never been a fan of setting secure to be off.

On the CSRF side I’m kind of two minds because while I think I understand the problem, I fear I’m too ignorant to have a well formed opinion. However it slightly seems to me as if CSRF protection isn’t something that is tied to JWT, but is a general issue that perhaps Jakarta EE should have an opinion on and perhaps if we added something here it might be like @LoginConfig and Arjan tells us we did it wrong and it should have been part of the Jakarta EE security spec.

Alasdair

--
You received this message because you are subscribed to the Google Groups "Eclipse MicroProfile" group.
To unsubscribe from this group and stop receiving emails from it, send an email to microprofile...@googlegroups.com.
To post to this group, send email to microp...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/microprofile/28c86921-758d-41df-945a-03b21af0aeb6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

James Roper

unread,
Mar 29, 2018, 1:37:18 AM3/29/18
to MicroProfile
I've implemented a number of CSRF filters before, including in Play Framework. Additionally, Play Framework has always had a stateless session mechanism, where the session data is stored in a cookie. Originally it used a proprietary format for formatting and signing the data, but in the latest release it switched to using JWT (which really was just an implementation detail, conceptually the approach hasn't changed at all). So I've got a fair amount of experience in using cookies with signed assertions (JWT or not), and protecting them with CSRF.

Firstly, CSRF is in no way a problem specific to JWT, as Alasdair points out. Any time you use cookies to hold any authentication or authorization assertions, you are vulnerable to CSRF. So the exact same problem occurs using Servlet sessions, with the session id cookie. It's a big disappointment that neither Java EE nor the Servlet spec in particular yet provides a CSRF solution, though some vendors provide proprietary solutions (I'm aware of Tomcat, I assume others do), and of course CSRF protection can be (and generally is) layered on top.

Secondly, CSRF protection is a moving target. Browsers have often introduced new APIs that subvert existing protection mechanisms, such as APIs that allow adding arbitrary headers to requests from other domains, or that allow posting content of any content type from other domains. When these protection mechanisms are subverted, it often means that requests that were previously allowed without CSRF tokens are now not allowed, and fixing it will break all the applications that depend on being allowed. You could say that breakage is acceptable, since without breaking them, they'll be vulnerable to CSRF, but that's an opinion that not everyone shares. But the point that I want to make here is it's very difficult to define a standard for CSRF, especially if you want to define when CSRF checks are and aren't required, because it's a moving target, and security vulnerabilities found in future may require changes at the spec level. Can we create a spec that can respond quickly to a zero day CSRF exploit?

Thirdly, while CSRF protection should be addressed outside of JWT, CSRF protection may need to be aware of JWT. The most common approach to CSRF protection is to put a token in the session (on the server side), and then require incoming requests to have a token, perhaps in a header, or as a query parameter in a URL. These tokens are then matched to decide if the request should proceed. If however, if there's no session, then any CSRF protection built to protect sessions is not needed, since CSRF involves exploiting an active session. This is often used to support API calls that don't come from the browser, and use an alternative authentication mechanism - eg OAuth - OAuth is not vulnerable to CSRF and so dosen't need CSRF checking, which is a good thing to avoid because it means you don't need to round trip to get a CSRF token every time you make an API call. So, a typical CSRF protection mechanism only does the check if there's a session. But, as soon as you start using JWT cookies, then you need to do checking not just if there's a session, but also if there's a JWT cookie. So the CSRF protection mechanism may need to be aware of JWT cookies, or provide some mechanism to allow it to know about them.

Finally, another thing that needs to be considered in the context of CSRF is CORS, we've found that our CORS support in Play Framework needs to be aware of CSRF and vice versa. I can't remember the exact reasons why, but I can find out if someone is interested. This is important if creating a standard for CSRF because there need to be the right integration points to support CORS in the CSRF mechanism, even if the standard doesn't have an in built support for CORS.

On 29 March 2018 at 03:59, Alasdair Nottingham <alasdair....@gmail.com> wrote:
I would have hoped that the http only and secure flags would be set by default and we could get away with not allowing them to be changed. I’ve never been a fan of setting secure to be off.

On the CSRF side I’m kind of two minds because while I think I understand the problem, I fear I’m too ignorant to have a well formed opinion. However it slightly seems to me as if CSRF protection isn’t something that is tied to JWT, but is a general issue that perhaps Jakarta EE should have an opinion on and perhaps if we added something here it might be like @LoginConfig and Arjan tells us we did it wrong and it should have been part of the Jakarta EE security spec.

Alasdair


On Mar 27, 2018, at 9:13 PM, Scott Stark <sst...@redhat.com> wrote:

Some CSRF references:


On Tuesday, March 27, 2018 at 5:44:19 PM UTC-7, Scott Stark wrote:
For the Define a standard Cookie for holding the MP-JWT token issue, defining a name (say MP-JWT-TOKEN) and format(just the x.y.z RS256 signed JWT base64 string) for the cookie is strait-forward, but it seems like we also need to enable some consistent configuration and behavior for CSRF/XSRF protection. If enabled, the MP-JWT service would need to include a XSRF-TOKEN cookie that contains a random string in addition to the MP-JWT-TOKEN, and validate the X-XSRF-TOKEN header to ensure it contains the XSRF-TOKEN cookie value last returned to the client.

Additional configuration settings for marking the MP-JWT-TOKEN as HttpOnly and Secure are probably also needed.

Feedback?



--
You received this message because you are subscribed to the Google Groups "Eclipse MicroProfile" group.
To unsubscribe from this group and stop receiving emails from it, send an email to microprofile+unsubscribe@googlegroups.com.

To post to this group, send email to microp...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/microprofile/28c86921-758d-41df-945a-03b21af0aeb6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Eclipse MicroProfile" group.
To unsubscribe from this group and stop receiving emails from it, send an email to microprofile+unsubscribe@googlegroups.com.

To post to this group, send email to microp...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
James Roper
Senior Octonaut

Lightbend – Build reactive apps!
Twitter: @jroper

Scott Stark

unread,
Mar 29, 2018, 11:13:42 PM3/29/18
to Eclipse MicroProfile
CSRF is certainly a general issue. I just brought it up in the context of adding a JWT cookie since the context of the exploit is cookies that convey authentication state. After looking into the related issues and use cases, this will need more discussion and identification of the usecases we want to support. I have created the following issue to track that effort:

On Wednesday, March 28, 2018 at 10:37:18 PM UTC-7, James Roper wrote:
I've implemented a number of CSRF filters before, including in Play Framework. Additionally, Play Framework has always had a stateless session mechanism, where the session data is stored in a cookie. Originally it used a proprietary format for formatting and signing the data, but in the latest release it switched to using JWT (which really was just an implementation detail, conceptually the approach hasn't changed at all). So I've got a fair amount of experience in using cookies with signed assertions (JWT or not), and protecting them with CSRF.

Firstly, CSRF is in no way a problem specific to JWT, as Alasdair points out. Any time you use cookies to hold any authentication or authorization assertions, you are vulnerable to CSRF. So the exact same problem occurs using Servlet sessions, with the session id cookie. It's a big disappointment that neither Java EE nor the Servlet spec in particular yet provides a CSRF solution, though some vendors provide proprietary solutions (I'm aware of Tomcat, I assume others do), and of course CSRF protection can be (and generally is) layered on top.

Secondly, CSRF protection is a moving target. Browsers have often introduced new APIs that subvert existing protection mechanisms, such as APIs that allow adding arbitrary headers to requests from other domains, or that allow posting content of any content type from other domains. When these protection mechanisms are subverted, it often means that requests that were previously allowed without CSRF tokens are now not allowed, and fixing it will break all the applications that depend on being allowed. You could say that breakage is acceptable, since without breaking them, they'll be vulnerable to CSRF, but that's an opinion that not everyone shares. But the point that I want to make here is it's very difficult to define a standard for CSRF, especially if you want to define when CSRF checks are and aren't required, because it's a moving target, and security vulnerabilities found in future may require changes at the spec level. Can we create a spec that can respond quickly to a zero day CSRF exploit?

Thirdly, while CSRF protection should be addressed outside of JWT, CSRF protection may need to be aware of JWT. The most common approach to CSRF protection is to put a token in the session (on the server side), and then require incoming requests to have a token, perhaps in a header, or as a query parameter in a URL. These tokens are then matched to decide if the request should proceed. If however, if there's no session, then any CSRF protection built to protect sessions is not needed, since CSRF involves exploiting an active session. This is often used to support API calls that don't come from the browser, and use an alternative authentication mechanism - eg OAuth - OAuth is not vulnerable to CSRF and so dosen't need CSRF checking, which is a good thing to avoid because it means you don't need to round trip to get a CSRF token every time you make an API call. So, a typical CSRF protection mechanism only does the check if there's a session. But, as soon as you start using JWT cookies, then you need to do checking not just if there's a session, but also if there's a JWT cookie. So the CSRF protection mechanism may need to be aware of JWT cookies, or provide some mechanism to allow it to know about them.

Finally, another thing that needs to be considered in the context of CSRF is CORS, we've found that our CORS support in Play Framework needs to be aware of CSRF and vice versa. I can't remember the exact reasons why, but I can find out if someone is interested. This is important if creating a standard for CSRF because there need to be the right integration points to support CORS in the CSRF mechanism, even if the standard doesn't have an in built support for CORS.
On 29 March 2018 at 03:59, Alasdair Nottingham <alasdair....@gmail.com> wrote:
I would have hoped that the http only and secure flags would be set by default and we could get away with not allowing them to be changed. I’ve never been a fan of setting secure to be off.

On the CSRF side I’m kind of two minds because while I think I understand the problem, I fear I’m too ignorant to have a well formed opinion. However it slightly seems to me as if CSRF protection isn’t something that is tied to JWT, but is a general issue that perhaps Jakarta EE should have an opinion on and perhaps if we added something here it might be like @LoginConfig and Arjan tells us we did it wrong and it should have been part of the Jakarta EE security spec.

Alasdair


On Mar 27, 2018, at 9:13 PM, Scott Stark <sst...@redhat.com> wrote:

Some CSRF references:


On Tuesday, March 27, 2018 at 5:44:19 PM UTC-7, Scott Stark wrote:
For the Define a standard Cookie for holding the MP-JWT token issue, defining a name (say MP-JWT-TOKEN) and format(just the x.y.z RS256 signed JWT base64 string) for the cookie is strait-forward, but it seems like we also need to enable some consistent configuration and behavior for CSRF/XSRF protection. If enabled, the MP-JWT service would need to include a XSRF-TOKEN cookie that contains a random string in addition to the MP-JWT-TOKEN, and validate the X-XSRF-TOKEN header to ensure it contains the XSRF-TOKEN cookie value last returned to the client.

Additional configuration settings for marking the MP-JWT-TOKEN as HttpOnly and Secure are probably also needed.

Feedback?



--
You received this message because you are subscribed to the Google Groups "Eclipse MicroProfile" group.
To unsubscribe from this group and stop receiving emails from it, send an email to microprofile...@googlegroups.com.

To post to this group, send email to microp...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/microprofile/28c86921-758d-41df-945a-03b21af0aeb6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Eclipse MicroProfile" group.
To unsubscribe from this group and stop receiving emails from it, send an email to microprofile...@googlegroups.com.

To post to this group, send email to microp...@googlegroups.com.

Scott Stark

unread,
Mar 29, 2018, 11:32:29 PM3/29/18
to Eclipse MicroProfile
So down to the real 1.1 task of defining the cookie name and value format. In looking around for even standards/naming conventions for cookies, I failed to find any. 

Critiques of just using MP-JWT-TOKEN with the value being the x.y.z RS256 signed JWT base64 string?

In terms of options, I would suggest that we add the secure and HttpOnly attributes by default, but have a standard MP config setting to disable each. A common usecase will be for client code to make use of claims in the token, in which case scripts based client code may need to disable HttpOnly. What is you feedback on this?



On Tuesday, March 27, 2018 at 5:44:19 PM UTC-7, Scott Stark wrote:

Alasdair Nottingham

unread,
Mar 29, 2018, 11:42:58 PM3/29/18
to 'Emily Jiang' via Eclipse MicroProfile
I don’t have an issue with x.y.z RS256 signed JWT base64, although I’ll defer to Chunlong as the expert in JWT from IBM on that.

Looking at precedent it seems _ is more common that - in cookie names. Also Java EE uses JSESSIONID for the session id, so maybe we can skip the separator based on that precedent. Also isn’t the T in JWT token? So could we just use MPJWT as the cookie name?

You have a use case about making http only configurable, but what about allowing the cookie over http? I know that some of my nervousness is FUD and paranoia, but I can’t see any good reason for sending an authentication token via http. 

Alasdair

--
You received this message because you are subscribed to the Google Groups "Eclipse MicroProfile" group.
To unsubscribe from this group and stop receiving emails from it, send an email to microprofile...@googlegroups.com.
To post to this group, send email to microp...@googlegroups.com.

Christian Kaltepoth

unread,
Mar 30, 2018, 2:21:36 AM3/30/18
to MicroProfile
Hi,

what about the "SameSite" cookie attribute? It is rather new but supported in most browsers. And actually its main purpose is to prevent CSRF attacks.


Unfortunately it is not supported in the Servlet API yet, but it should work fine if the cookie header is created manually instead of using HttpServletResponse#addCookie().

Christian



--
You received this message because you are subscribed to the Google Groups "Eclipse MicroProfile" group.
To unsubscribe from this group and stop receiving emails from it, send an email to microprofile...@googlegroups.com.
To post to this group, send email to microp...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/microprofile/a313328a-cbc4-4040-8539-b3e198439041%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--

Scott Stark

unread,
Mar 30, 2018, 7:56:29 PM3/30/18
to Eclipse MicroProfile


On Thursday, March 29, 2018 at 8:42:58 PM UTC-7, Alasdair Nottingham wrote:
I don’t have an issue with x.y.z RS256 signed JWT base64, although I’ll defer to Chunlong as the expert in JWT from IBM on that.

Looking at precedent it seems _ is more common that - in cookie names. Also Java EE uses JSESSIONID for the session id, so maybe we can skip the separator based on that precedent. Also isn’t the T in JWT token? So could we just use MPJWT as the cookie name?
MPJWT is fine with me.
 

You have a use case about making http only configurable, but what about allowing the cookie over http? I know that some of my nervousness is FUD and paranoia, but I can’t see any good reason for sending an authentication token via http. 


I don't have a case for not using https, just that if we are setting a value, in my experience, someone will want the control to unset it.
 

Scott Stark

unread,
Mar 30, 2018, 8:07:36 PM3/30/18
to Eclipse MicroProfile
I don't see any harm in enabling it by default and providing a configuration option to control the setting.

Christian Kaltepoth

unread,
Mar 31, 2018, 2:17:16 AM3/31/18
to MicroProfile
Hi,
 
You have a use case about making http only configurable, but what about allowing the cookie over http? I know that some of my nervousness is FUD and paranoia, but I can’t see any good reason for sending an authentication token via http. 
I don't have a case for not using https, just that if we are setting a value, in my experience, someone will want the control to unset it.

Disabling secure cookies especially makes sense at development time. So it should definitely be configurable. 

Christian

Arjan Tijms

unread,
Mar 31, 2018, 1:51:20 PM3/31/18
to Eclipse MicroProfile
Hi,

Regarding the @LoginConfig, I don’t want to be a nuisance ;) But the risk we’re running here is that the JWT spec becomes its own security spec.

Even without Jakarta EE, think of what happens when MicroProfile would also add authentication mechanisms for OAuth2 and something for say Yubikey. Would they all depend on JWT then, even though there’s no logical dependency?

Or would some general security things be in JWT, some others in OAuth and yet some others in Yubikey, so that eventually they all depend on each other?

Of course the main issue here is that JWT was started without having a security foundation. JAX-RS and CDI both say something about this, but not enough to really build on.

As MP are fast moving it’s not the end of the world to have something in it now, and then deprecate and remove it relatively soon again.

Kind regards,
Arjan

Scott Stark

unread,
Mar 31, 2018, 10:57:56 PM3/31/18
to Eclipse MicroProfile
I'm not sure what you mean by the reference to @LoginConfig. If it is a reference to introducing security aspects that may be better defined elsewhere, there are multiple problems with that:
1. Java EE has not sufficiently defined many security behaviors, and Jarkata EE therefore inherits this issue. Further, it will be some time before there is a functioning Jakarta EE process that gets things moving again.
2. Independent of there being functioning Jakarta EE process, there is no agreement that the Microprofile effort simply folds into that. It certainly builds on a subset of the Jakarta EE specs, but how and the
evolution of the usecases around those may well be a different process.
3. We are creating an architecture group for the purpose of consistency across Microprofile features. When we have multiple features start dealing with security aspects, we can raise the need for a Microprofile security spec, workingroup, etc, to centralize the common behaviors and even apis/code.

Arjan Tijms

unread,
Apr 1, 2018, 5:55:58 AM4/1/18
to Eclipse MicroProfile
Hi,


On Sunday, April 1, 2018 at 4:57:56 AM UTC+2, Scott Stark wrote:
I'm not sure what you mean by the reference to @LoginConfig.

Oh, this was in reply to Alasdair. Somehow that msg wasn't quoted. Specifically, in reply to this:


Alasdair Nottingham 
>  perhaps if we added something here it might be like @LoginConfig and Arjan tells us we did it wrong and it should have been part of the Jakarta EE security spec.

Kind regards,
Arjan

Arjan Tijms

unread,
Apr 3, 2018, 8:00:00 AM4/3/18
to Eclipse MicroProfile
Btw


On Sunday, 1 April, 2018 at 4:57:56 AM UTC+2, Scott Stark wrote:
1. Java EE has not sufficiently defined many security behaviors, and Jarkata EE therefore inherits this issue.

I agree that many security aspects were not sufficiently defined in Java EE. 

But, for MP JWT what has been defined proved to be enough, as I could fully implement MP JWT using only standard Java EE Security, CDI and JAX-RS APIs.

Kind regards,
Arjan
 

Alasdair Nottingham

unread,
Apr 3, 2018, 1:11:57 PM4/3/18
to microp...@googlegroups.com
I tend to take the view that it is better to apply security in development since you can’t then forget to change the development behaviour. A good server should make it easy to do self signed certs in development.

Alasdair

--
You received this message because you are subscribed to the Google Groups "Eclipse MicroProfile" group.
To unsubscribe from this group and stop receiving emails from it, send an email to microprofile...@googlegroups.com.
To post to this group, send email to microp...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages