Generate JWTs with Django

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

Generate JWTs with Django

Claude Paroz
Hi all,

With the recent addition of the algorithm parameter to the signing.Signer class, it's now rather straightforward for Django to generate HS256 (non-encrypted) JSON Web Tokens.
With a growing popularity of JS-client/Django server communications (DRF and al.), I think there might be some interest for Django to be able to generate and decode such tokens. For any other types of JWTs which generally require access to a cryptography module, we can point users to third-party libs like PyJWT (the docs should be clear about that).

I made a proof-of-concept PR (docs missing) here:
 - https://github.com/django/django/pull/12728

What people here think about that proposal?

Claude

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/5f67fefb-d158-4722-b704-6c34d72692a8%40googlegroups.com.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Abhijeet Viswa
Hi,

You might want check out django-restframework-simplejwt. It requires the Django Rest Framework. But, then again, if you are making an API, you'd already be using it.

Regards,
Abhijeet

On Thu, 16 Apr, 2020, 00:39 Claude Paroz, <[hidden email]> wrote:
Hi all,

With the recent addition of the algorithm parameter to the signing.Signer class, it's now rather straightforward for Django to generate HS256 (non-encrypted) JSON Web Tokens.
With a growing popularity of JS-client/Django server communications (DRF and al.), I think there might be some interest for Django to be able to generate and decode such tokens. For any other types of JWTs which generally require access to a cryptography module, we can point users to third-party libs like PyJWT (the docs should be clear about that).

I made a proof-of-concept PR (docs missing) here:
 - https://github.com/django/django/pull/12728

What people here think about that proposal?

Claude

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/5f67fefb-d158-4722-b704-6c34d72692a8%40googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAP1-Yrqiryo%2BuapQHkLjebwP7aaOQ8igSx3_cr6Q1Q16bKgaRw%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Claude Paroz
Thanks Abhijeet for the pointer, I know there are some rather complete
JWT libs around, but my proposal is not about a complete package to
manage JWT in general.
It's rather some low level ability for Django to produce and decode
simple HS256 JWT. Then other third-party libs could build on that
ability to write more elaborate packages.

The main doubt I have about my proposal is whether HS256 JWTs are too
limited for most usages or in the contrary if they are appropriate for a
fair amount of use cases.

Claude

Le 15.04.20 à 21:13, Abhijeet Viswa a écrit :

> Hi,
>
> You might want check out django-restframework-simplejwt. It requires the
> Django Rest Framework. But, then again, if you are making an API, you'd
> already be using it.
>
> Regards,
> Abhijeet
>
> On Thu, 16 Apr, 2020, 00:39 Claude Paroz, <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Hi all,
>
>     With the recent addition of the algorithm parameter to the
>     signing.Signer class, it's now rather straightforward for Django to
>     generate HS256 (non-encrypted) JSON Web Tokens.
>     With a growing popularity of JS-client/Django server communications
>     (DRF and al.), I think there might be some interest for Django to be
>     able to generate and decode such tokens. For any other types of JWTs
>     which generally require access to a cryptography module, we can
>     point users to third-party libs like PyJWT (the docs should be clear
>     about that).
>
>     I made a proof-of-concept PR (docs missing) here:
>      - https://github.com/django/django/pull/12728
>
>     What people here think about that proposal?
>
>     Claude

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/9f5f4df0-64d3-68aa-0ae7-302e037d406a%402xlibre.net.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Claude Paroz
For your information, I now added docs to the tentative patch:

https://github.com/django/django/pull/12728

Claude

Le 15.04.20 à 21:26, Claude Paroz a écrit :

> Thanks Abhijeet for the pointer, I know there are some rather complete
> JWT libs around, but my proposal is not about a complete package to
> manage JWT in general.
> It's rather some low level ability for Django to produce and decode
> simple HS256 JWT. Then other third-party libs could build on that
> ability to write more elaborate packages.
>
> The main doubt I have about my proposal is whether HS256 JWTs are too
> limited for most usages or in the contrary if they are appropriate for a
> fair amount of use cases.
>
> Claude
>
> Le 15.04.20 à 21:13, Abhijeet Viswa a écrit :
>> Hi,
>>
>> You might want check out django-restframework-simplejwt. It requires the
>> Django Rest Framework. But, then again, if you are making an API, you'd
>> already be using it.
>>
>> Regards,
>> Abhijeet
>>
>> On Thu, 16 Apr, 2020, 00:39 Claude Paroz, <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>>     Hi all,
>>
>>     With the recent addition of the algorithm parameter to the
>>     signing.Signer class, it's now rather straightforward for Django to
>>     generate HS256 (non-encrypted) JSON Web Tokens.
>>     With a growing popularity of JS-client/Django server communications
>>     (DRF and al.), I think there might be some interest for Django to be
>>     able to generate and decode such tokens. For any other types of JWTs
>>     which generally require access to a cryptography module, we can
>>     point users to third-party libs like PyJWT (the docs should be clear
>>     about that).
>>
>>     I made a proof-of-concept PR (docs missing) here:
>>      - https://github.com/django/django/pull/12728
>>
>>     What people here think about that proposal?
>>
>>     Claude

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/87ddf575-0756-b99e-51d8-99de1b258c21%402xlibre.net.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Adam Johnson-2
Hi Claude

JWT's are indeed popular for API's. I think if Django was being created "from the ground up" today, JWT's would be a no-brainer to include, so it seems reasonable to add some support.

I've had a look at the PR, and yes it is indeed a small amount of code - and thanks for the documentation.

Have you got any data on how often encrypted vs. non-encrypted JWT's are used? Personally I can't remember from the projects I've worked on which format has been used.

Thanks,

Adam

On Wed, 22 Apr 2020 at 09:57, Claude Paroz <[hidden email]> wrote:
For your information, I now added docs to the tentative patch:

https://github.com/django/django/pull/12728

Claude

Le 15.04.20 à 21:26, Claude Paroz a écrit :
> Thanks Abhijeet for the pointer, I know there are some rather complete
> JWT libs around, but my proposal is not about a complete package to
> manage JWT in general.
> It's rather some low level ability for Django to produce and decode
> simple HS256 JWT. Then other third-party libs could build on that
> ability to write more elaborate packages.
>
> The main doubt I have about my proposal is whether HS256 JWTs are too
> limited for most usages or in the contrary if they are appropriate for a
> fair amount of use cases.
>
> Claude
>
> Le 15.04.20 à 21:13, Abhijeet Viswa a écrit :
>> Hi,
>>
>> You might want check out django-restframework-simplejwt. It requires the
>> Django Rest Framework. But, then again, if you are making an API, you'd
>> already be using it.
>>
>> Regards,
>> Abhijeet
>>
>> On Thu, 16 Apr, 2020, 00:39 Claude Paroz, <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>>     Hi all,
>>
>>     With the recent addition of the algorithm parameter to the
>>     signing.Signer class, it's now rather straightforward for Django to
>>     generate HS256 (non-encrypted) JSON Web Tokens.
>>     With a growing popularity of JS-client/Django server communications
>>     (DRF and al.), I think there might be some interest for Django to be
>>     able to generate and decode such tokens. For any other types of JWTs
>>     which generally require access to a cryptography module, we can
>>     point users to third-party libs like PyJWT (the docs should be clear
>>     about that).
>>
>>     I made a proof-of-concept PR (docs missing) here:
>>      - https://github.com/django/django/pull/12728
>>
>>     What people here think about that proposal?
>>
>>     Claude

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/87ddf575-0756-b99e-51d8-99de1b258c21%402xlibre.net.


--
Adam

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAMyDDM2x%3D%2BB0xM0YRauHxwDDm2ymxeGmYqYCVdOMJS94-F4Xdg%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Markus Holtermann
Nice work, Claude!

However, dealing with JWTs, and especially verifying them is notoriously hard and fragile. Frankly, I think I'd rather see smaller libraries do one job and do it well, than having Django implement an incomplete JWT spec. As far as I can tell, only HS256 signing/verification is implemented, but nothing else, right?

Cheers,

Markus

On Wed, Apr 22, 2020, at 3:38 PM, Adam Johnson wrote:

> Hi Claude
>
> JWT's are indeed popular for API's. I think if Django was being created
> "from the ground up" today, JWT's would be a no-brainer to include, so
> it seems reasonable to add some support.
>
> I've had a look at the PR, and yes it is indeed a small amount of code
> - and thanks for the documentation.
>
> Have you got any data on how often encrypted vs. non-encrypted JWT's
> are used? Personally I can't remember from the projects I've worked on
> which format has been used.
>
> Thanks,
>
> Adam
>
> On Wed, 22 Apr 2020 at 09:57, Claude Paroz <[hidden email]> wrote:
> > For your information, I now added docs to the tentative patch:
> >
> > https://github.com/django/django/pull/12728
> >
> >  Claude
> >
> >  Le 15.04.20 à 21:26, Claude Paroz a écrit :
> >  > Thanks Abhijeet for the pointer, I know there are some rather complete
> >  > JWT libs around, but my proposal is not about a complete package to
> >  > manage JWT in general.
> >  > It's rather some low level ability for Django to produce and decode
> >  > simple HS256 JWT. Then other third-party libs could build on that
> >  > ability to write more elaborate packages.
> >  >
> >  > The main doubt I have about my proposal is whether HS256 JWTs are too
> >  > limited for most usages or in the contrary if they are appropriate for a
> >  > fair amount of use cases.
> >  >
> >  > Claude
> >  >
> >  > Le 15.04.20 à 21:13, Abhijeet Viswa a écrit :
> >  >> Hi,
> >  >>
> >  >> You might want check out django-restframework-simplejwt. It requires the
> >  >> Django Rest Framework. But, then again, if you are making an API, you'd
> >  >> already be using it.
> >  >>
> >  >> Regards,
> >  >> Abhijeet
> >  >>
> >  >> On Thu, 16 Apr, 2020, 00:39 Claude Paroz, <[hidden email]
> >  >> <mailto:[hidden email]>> wrote:
> >  >>
> >  >> Hi all,
> >  >>
> >  >> With the recent addition of the algorithm parameter to the
> >  >> signing.Signer class, it's now rather straightforward for Django to
> >  >> generate HS256 (non-encrypted) JSON Web Tokens.
> >  >> With a growing popularity of JS-client/Django server communications
> >  >> (DRF and al.), I think there might be some interest for Django to be
> >  >> able to generate and decode such tokens. For any other types of JWTs
> >  >> which generally require access to a cryptography module, we can
> >  >> point users to third-party libs like PyJWT (the docs should be clear
> >  >> about that).
> >  >>
> >  >> I made a proof-of-concept PR (docs missing) here:
> >  >> - https://github.com/django/django/pull/12728
> >  >>
> >  >> What people here think about that proposal?
> >  >>
> >  >> Claude
> >
> >  --
> >  You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
> >  To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email] <mailto:django-developers%[hidden email]>.
> >  To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/87ddf575-0756-b99e-51d8-99de1b258c21%402xlibre.net.
>
>
> --
> Adam
>
>  --
>  You received this message because you are subscribed to the Google
> Groups "Django developers (Contributions to Django itself)" group.
>  To unsubscribe from this group and stop receiving emails from it, send
> an email to [hidden email].
>  To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CAMyDDM2x%3D%2BB0xM0YRauHxwDDm2ymxeGmYqYCVdOMJS94-F4Xdg%40mail.gmail.com <https://groups.google.com/d/msgid/django-developers/CAMyDDM2x%3D%2BB0xM0YRauHxwDDm2ymxeGmYqYCVdOMJS94-F4Xdg%40mail.gmail.com?utm_medium=email&utm_source=footer>.

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/bb569a66-38d5-4165-8da9-fa0cd6a799da%40www.fastmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Claude Paroz
Hey Markus,

In fact, when I had to implement that in one of my projects, I realized that Django has already most tools needed to (in my opinion) properly handle those tokens. And indeed, this only covers HS256-type of JWTs, for any other type, we would recommend using a third-party package (see the docs type of my patch).
If we had to reimplement all the hard work of signing and verifying, I would not have proposed this addition to Django.

Claude

Le vendredi 24 avril 2020 16:32:27 UTC+2, Markus Holtermann a écrit :
Nice work, Claude!

However, dealing with JWTs, and especially verifying them is notoriously hard and fragile. Frankly, I think I'd rather see smaller libraries do one job and do it well, than having Django implement an incomplete JWT spec. As far as I can tell, only HS256 signing/verification is implemented, but nothing else, right?

Cheers,

Markus

On Wed, Apr 22, 2020, at 3:38 PM, Adam Johnson wrote:

> Hi Claude
>
> JWT's are indeed popular for API's. I think if Django was being created
> "from the ground up" today, JWT's would be a no-brainer to include, so
> it seems reasonable to add some support.
>
> I've had a look at the PR, and yes it is indeed a small amount of code
> - and thanks for the documentation.
>
> Have you got any data on how often encrypted vs. non-encrypted JWT's
> are used? Personally I can't remember from the projects I've worked on
> which format has been used.
>
> Thanks,
>
> Adam
>
> On Wed, 22 Apr 2020 at 09:57, Claude Paroz <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="Wanrvtv9AAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">cla...@...> wrote:
> > For your information, I now added docs to the tentative patch:
> >
> > <a href="https://github.com/django/django/pull/12728" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdjango%2Fdjango%2Fpull%2F12728\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFg3tupYw0gbw7rpOzxWjJSUaUb_w&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdjango%2Fdjango%2Fpull%2F12728\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFg3tupYw0gbw7rpOzxWjJSUaUb_w&#39;;return true;">https://github.com/django/django/pull/12728
> >
> >  Claude
> >
> >  Le 15.04.20 à 21:26, Claude Paroz a écrit :
> >  > Thanks Abhijeet for the pointer, I know there are some rather complete
> >  > JWT libs around, but my proposal is not about a complete package to
> >  > manage JWT in general.
> >  > It's rather some low level ability for Django to produce and decode
> >  > simple HS256 JWT. Then other third-party libs could build on that
> >  > ability to write more elaborate packages.
> >  >
> >  > The main doubt I have about my proposal is whether HS256 JWTs are too
> >  > limited for most usages or in the contrary if they are appropriate for a
> >  > fair amount of use cases.
> >  >
> >  > Claude
> >  >
> >  > Le 15.04.20 à 21:13, Abhijeet Viswa a écrit :
> >  >> Hi,
> >  >>
> >  >> You might want check out django-restframework-simplejwt. It requires the
> >  >> Django Rest Framework. But, then again, if you are making an API, you'd
> >  >> already be using it.
> >  >>
> >  >> Regards,
> >  >> Abhijeet
> >  >>
> >  >> On Thu, 16 Apr, 2020, 00:39 Claude Paroz, <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="Wanrvtv9AAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">cla...@...
> >  >> <mailto:<a href="javascript:" target="_blank" gdf-obfuscated-mailto="Wanrvtv9AAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">cla...@...>> wrote:
> >  >>
> >  >> Hi all,
> >  >>
> >  >> With the recent addition of the algorithm parameter to the
> >  >> signing.Signer class, it's now rather straightforward for Django to
> >  >> generate HS256 (non-encrypted) JSON Web Tokens.
> >  >> With a growing popularity of JS-client/Django server communications
> >  >> (DRF and al.), I think there might be some interest for Django to be
> >  >> able to generate and decode such tokens. For any other types of JWTs
> >  >> which generally require access to a cryptography module, we can
> >  >> point users to third-party libs like PyJWT (the docs should be clear
> >  >> about that).
> >  >>
> >  >> I made a proof-of-concept PR (docs missing) here:
> >  >> - <a href="https://github.com/django/django/pull/12728" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdjango%2Fdjango%2Fpull%2F12728\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFg3tupYw0gbw7rpOzxWjJSUaUb_w&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdjango%2Fdjango%2Fpull%2F12728\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFg3tupYw0gbw7rpOzxWjJSUaUb_w&#39;;return true;">https://github.com/django/django/pull/12728
> >  >>
> >  >> What people here think about that proposal?
> >  >>
> >  >> Claude

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/3d7304c8-79d7-4ea5-a602-15131f85b7ee%40googlegroups.com.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

James Bennett
I understand that this will probably get shouted down due to the
popularity of JWTs, but: I don't think Django should include any type
of JWT support in the core framework.

JWTs are an absolute security nightmare. Some of the Django security
team have heard me rant on this topic already, but: there is no such
thing as a safe JWT implementation, because there are fundamental
flaws in the design of JWT that cannot be remedied by just writing
better implementations. Supporting them in Django, even to the minimal
extent in the current PR, would encourage users of Django to adopt
them, which goes against our historical trend of pushing best
practices when it comes to application security, and would
significantly add to the security team's burden because of the
increased attack surface JWT support would open up.

If Django does end up shipping some type of JWT support, I'd lobby
very strongly for declaring it out of scope for our security process,
and labeling it "use at your own risk".

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAL13Cg8Csr1ageZCEKm9bd12Tb_vosx_xLSV%2B8WfvoWi01%2BfPA%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Ryan Hiebert-2


On Sun, Apr 26, 2020 at 8:29 AM James Bennett <[hidden email]> wrote:
JWTs are an absolute security nightmare. Some of the Django security
team have heard me rant on this topic already, but: there is no such
thing as a safe JWT implementation, because there are fundamental
flaws in the design of JWT that cannot be remedied by just writing
better implementations.

Given this thesis, your conclusion makes sense. I use JWTs in my application, because my domain is particularly suited to it IMO, and while I can't speak for everyone on this list, I'd be interested to hear your complaints about the design of JWTs. For my own thinking, I find that the inclusion of the standardized algorithm field was a design mistake. It can be papered over by a good library implementation, but that so many libraries got it wrong is evidence of a flaw in the protocol design, IMO.

However, I'm not aware of any other standard payload-signing mechanism that has the well-defined capabilities that JWTs have, without that issue. That's fairly likely to be ignorance on my part, and if a more suitable standard were available to me, I'd happily switch my application to using it. Obviously JWTs are indeed popular, and I don't particularly find that the issue I mentioned above to be a total showstopper (although obviously very unfortunate).

Perhaps in email or a blog post or just a list of links, would you be willing to share your complaints? Are there better designs for a similar protocol that overcome your objections?

Ryan

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CABpHFHQ6M6ODzjX9aXxY-nbZRu5hFHq-nUcviGvzdX8U_NwePw%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Adam Johnson-2
James, I too would like to know your criticisms! I've always understood that they aren't much different to signed cookies, but I haven't looked too deeply at them.

On Sun, 26 Apr 2020 at 16:00, Ryan Hiebert <[hidden email]> wrote:


On Sun, Apr 26, 2020 at 8:29 AM James Bennett <[hidden email]> wrote:
JWTs are an absolute security nightmare. Some of the Django security
team have heard me rant on this topic already, but: there is no such
thing as a safe JWT implementation, because there are fundamental
flaws in the design of JWT that cannot be remedied by just writing
better implementations.

Given this thesis, your conclusion makes sense. I use JWTs in my application, because my domain is particularly suited to it IMO, and while I can't speak for everyone on this list, I'd be interested to hear your complaints about the design of JWTs. For my own thinking, I find that the inclusion of the standardized algorithm field was a design mistake. It can be papered over by a good library implementation, but that so many libraries got it wrong is evidence of a flaw in the protocol design, IMO.

However, I'm not aware of any other standard payload-signing mechanism that has the well-defined capabilities that JWTs have, without that issue. That's fairly likely to be ignorance on my part, and if a more suitable standard were available to me, I'd happily switch my application to using it. Obviously JWTs are indeed popular, and I don't particularly find that the issue I mentioned above to be a total showstopper (although obviously very unfortunate).

Perhaps in email or a blog post or just a list of links, would you be willing to share your complaints? Are there better designs for a similar protocol that overcome your objections?

Ryan

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CABpHFHQ6M6ODzjX9aXxY-nbZRu5hFHq-nUcviGvzdX8U_NwePw%40mail.gmail.com.


--
Adam

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAMyDDM10C8CrXNCj7tsUgvJ-xBRG8LixMT1djwntpt4%2BZZ_fkQ%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

James Bennett
On Sun, Apr 26, 2020 at 8:46 AM Adam Johnson <[hidden email]> wrote:
>
> James, I too would like to know your criticisms! I've always understood that they aren't much different to signed cookies, but I haven't looked too deeply at them.

Well, people asked. So.

The short summary is: JWT is over-complex, puts too much power in the
attacker's hands, has too many configuration knobs, and makes poor
cryptographic choices. This is why we see vulnerabilities in JWT
libraries and JWT-using systems again and again and again.

And even if you get every single bit of it right, in the ideal perfect
world with the ideal perfect implementation, the payoff is you've put
in a ton of work to get something that already existed: signed
cookies, for the use case of session identification, or any of several
better token or token-like systems -- everything from PASETO to just
timestamped HMAC'd values -- for the use case of inter-service
communication.

The longer version goes more like this...

JWT is a more complex thing than many people appreciate. In fact, it's
at least *five* things, each specified in its own RFC, plus some more
you have to know about and implement if you want any hope of getting
the actually-sorta-secure version. And right off the bat, that's
worrying: the more different things you have to implement, and the
more places you have to look to find out what and how to implement,
the more opportunities there are to make mistakes.

This complexity comes from the sheer number of different options JWT
tries to support, which in turn is an anti-pattern. JWTs may be
signed, or they may not. They may be encrypted, or they may not. There
are multiple different options for how to sign, how to encrypt, how to
manage and specify keys... in a well-designed system there would be
far fewer options. Ideally, there'd be only one option, and the
solution for a vulnerability being found in it would be to increment
the version of the underlying spec, and change to something
better.

Anyway. In JWT, signature and encryption schemes are effectively
negotiable, which is yet another anti-pattern: you are putting
enormous power in the hands of attackers to negotiate you down to a
bad, or nonexistent, cipher/algorithm for encryption or signing. TLS/SSL
learned this lesson the hard way; JWT has chosen not to learn it at
all. Worse, JWT embeds the negotiation about how to handle the token
into the token itself. This is just asking for trouble, and in fact
trouble has routinely occurred. As a somewhat sarcastic author of my
acquaintance put it:

> It is extraordinarily easy to screw up JWT. JWT is a JSON format
> where you have to parse and interpret a JSON document to figure out
> how to decrypt and authenticate a JSON document. It has revived bugs
> we thought long dead, like “repurposing asymmetric public keys as
> symmetric private keys”.

(from: https://latacora.micro.blog/a-childs-garden/)

More succinctly: JWTs inherently and unavoidably violate the
Cryptographic Doom Principle
(https://moxie.org/blog/the-cryptographic-doom-principle/). Worse,
JWTs put full control of the violation in the hands of the attacker,
who -- thanks to the high level of configurability JWT offers -- is
free to find the set of options most likely to compromise you, and
foist them on you.

That quoted line above about revived long-dead bugs is no joke,
incidentally. Here's one from a few years back:

https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/

Five different libraries, written in three different languages, all
had the same bug. I once had the misfortune of arguing with someone
who attributed this to the libraries being built by bad programmers,
or in bad languages. But I personally tend to agree with a line from
this talk:

https://www.okta.com/video/oktane19-cryptographic-wrong-answers/

> Now you can say look those are all implementation vulnerabilities,
> it's not actually JWTs fault, I disagree. If I can find the same
> vulnerability in five popular libraries, then maybe the spec did a
> bad job of making sure people avoided that vulnerability.

So to completely head off the "it's just bad implementations"
argument, let's turn to the specs themselves: RFCs 7515, 7516, 7517,
7518, and 7519 are the core specifications that make up with is
commonly called "JWT" (and in RFC-land is more properly called "JOSE"
-- "JSON Object Signing and Encryption", of which the token format is
but one part).

The JOSE RFCs make a number of choices regarding default sets of
standardized cryptographic options. For example, RFC 7518 standardizes
thirteen signature algorithm options, seventeen encryption key
management options, and six different encryption cipher options.

This is already a problem -- that's an absolutely gigantic
combinatorial space of options! But then it gets worse.

Let's look just at the first table of options in that RFC, which is
for signing algorithms. It categorizes them as "Required",
"Recommended+", "Recommended", or "Optional". It then places into its
"Recommended" category options like RSASSA-PKCS-v1_5, which was known
to be vulnerable to Bleichenbacher's attack nine years before this RFC
was written (and Bleichenbacher's attack on PKCS#1 in general had been
known for 17 years at that point).

And then if we read a bit further we find ECDSA with P-256 is in the
"Recommended+" category, which the RFC helpfully says means that it is
likely to be bumped up to "Required" in the future. The P-256 curve
is... controversial, to say the least, and it took several additional
years before RFC 8037 finally standardized a better alternative
(Ed25519).

And that's just one quick glance at one table of one set of the
available options in one of the five core RFCs.

Here's another set of critical vulnerabilities:

https://blogs.adobe.com/security/2017/03/critical-vulnerability-uncovered-in-json-encryption.html

Five different libraries, for three different languages (and a
*different* set of libraries and languages than the previous
critical-vulnerability post I linked), all vulnerable to the same
basic invalid-curve attack.

Here's another one from just ten days ago:

https://insomniasec.com/blog/auth0-jwt-validation-bypass

Auth0's JWT validation was tricked into accepting unsigned tokens
thanks to a bug in parsing the (attacker-provided and
attacker-selected!) "alg" header parameter.

I could go on with this, but the general idea I'm trying to get across
is: JWT's issues are not just due to specific implementations being
bad. Several are issues that come with JWT itself, and are baked into
its design and specifications. The existence of vulnerabilities in
popular libraries is thus an expected consequence; no amount of
brilliance on the part of library authors can correct for the inherent
problems with JWT.

Meanwhile, we have access to alternatives that are simpler, more
robust, or often both. Django already supports at least two of them
out-of-the-box. As a result, I remain *strongly* against implementing
support for JWTs in Django, in any form, even the draft subset
implementation Claude has posted.

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAL13Cg8FkiPVi8oCuxtBUsiDoOUezXa%2B%2Bv5b75QxcZoDUtxy7A%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Ryan Hiebert-2
On Sun, Apr 26, 2020 at 9:53 PM James Bennett <[hidden email]> wrote:
On Sun, Apr 26, 2020 at 8:46 AM Adam Johnson <[hidden email]> wrote:

The short summary is: JWT is over-complex, puts too much power in the
attacker's hands, has too many configuration knobs, and makes poor
cryptographic choices. This is why we see vulnerabilities in JWT
libraries and JWT-using systems again and again and again.

And even if you get every single bit of it right, in the ideal perfect
world with the ideal perfect implementation, the payoff is you've put
in a ton of work to get something that already existed: signed
cookies, for the use case of session identification, or any of several
better token or token-like systems -- everything from PASETO to just
timestamped HMAC'd values -- for the use case of inter-service
communication.

Thank you very much for this write-up. The mention of PASETO was particularly helpful to me. I was aware of the big all-library issue due to algorithm negotiation and public/symmetric forgery, but not the others you mentioned.

For my use-case, I need a signed payload that is server-verified and client-readable. It sounds like PASETO is what you might recommend that I use, instead of JWTs, IIUC.

Would you think that the motivation that started this thread might be well served with having that as PASETO, or would it be better in your estimation to avoid either JWT or PASETO in Django at this time? I can imagine that Django using PASETO could give it a signal boost, but of course if there were discovered some design flaw there, it would also entrench it more as well as making it a security issue that Django has to address.

Either way, I really appreciate you taking the time to let us hear your thoughts.

Ryan

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CABpHFHTTYkQ3FsK4LOj%2B_kc-ZMyicdBSFTqFd1e370EnFHoPXA%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Tom Forbes
In reply to this post by James Bennett
Thank you for the fantastic summary James. You’re spot on about the various implementation issues that plague JWT libraries.

While I think it’s an OK technology if you use a very explicit subset and you know what you’re doing (see https://github.com/google/jws) it is indeed a bit of a minefield and I’m not sure we should be promoting it.

That being said, are signed cookies really a suitable replacement for JWTs? Right off the bat there is a size limit that’s shared with other cookies on your domain, and you might not want to (or be able to) encode the data in a cookie to begin with.

Maybe we can update the docs to show how you you would might use some of the signing primitives instead of JWTs, but this also sounds a bit dangerous 🤷‍♂️ 

On 27 Apr 2020, at 03:53, James Bennett <[hidden email]> wrote:

On Sun, Apr 26, 2020 at 8:46 AM Adam Johnson <[hidden email]> wrote:

James, I too would like to know your criticisms! I've always understood that they aren't much different to signed cookies, but I haven't looked too deeply at them.

Well, people asked. So.

The short summary is: JWT is over-complex, puts too much power in the
attacker's hands, has too many configuration knobs, and makes poor
cryptographic choices. This is why we see vulnerabilities in JWT
libraries and JWT-using systems again and again and again.

And even if you get every single bit of it right, in the ideal perfect
world with the ideal perfect implementation, the payoff is you've put
in a ton of work to get something that already existed: signed
cookies, for the use case of session identification, or any of several
better token or token-like systems -- everything from PASETO to just
timestamped HMAC'd values -- for the use case of inter-service
communication.

The longer version goes more like this...

JWT is a more complex thing than many people appreciate. In fact, it's
at least *five* things, each specified in its own RFC, plus some more
you have to know about and implement if you want any hope of getting
the actually-sorta-secure version. And right off the bat, that's
worrying: the more different things you have to implement, and the
more places you have to look to find out what and how to implement,
the more opportunities there are to make mistakes.

This complexity comes from the sheer number of different options JWT
tries to support, which in turn is an anti-pattern. JWTs may be
signed, or they may not. They may be encrypted, or they may not. There
are multiple different options for how to sign, how to encrypt, how to
manage and specify keys... in a well-designed system there would be
far fewer options. Ideally, there'd be only one option, and the
solution for a vulnerability being found in it would be to increment
the version of the underlying spec, and change to something
better.

Anyway. In JWT, signature and encryption schemes are effectively
negotiable, which is yet another anti-pattern: you are putting
enormous power in the hands of attackers to negotiate you down to a
bad, or nonexistent, cipher/algorithm for encryption or signing. TLS/SSL
learned this lesson the hard way; JWT has chosen not to learn it at
all. Worse, JWT embeds the negotiation about how to handle the token
into the token itself. This is just asking for trouble, and in fact
trouble has routinely occurred. As a somewhat sarcastic author of my
acquaintance put it:

It is extraordinarily easy to screw up JWT. JWT is a JSON format
where you have to parse and interpret a JSON document to figure out
how to decrypt and authenticate a JSON document. It has revived bugs
we thought long dead, like “repurposing asymmetric public keys as
symmetric private keys”.

(from: https://latacora.micro.blog/a-childs-garden/)

More succinctly: JWTs inherently and unavoidably violate the
Cryptographic Doom Principle
(https://moxie.org/blog/the-cryptographic-doom-principle/). Worse,
JWTs put full control of the violation in the hands of the attacker,
who -- thanks to the high level of configurability JWT offers -- is
free to find the set of options most likely to compromise you, and
foist them on you.

That quoted line above about revived long-dead bugs is no joke,
incidentally. Here's one from a few years back:

https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/

Five different libraries, written in three different languages, all
had the same bug. I once had the misfortune of arguing with someone
who attributed this to the libraries being built by bad programmers,
or in bad languages. But I personally tend to agree with a line from
this talk:

https://www.okta.com/video/oktane19-cryptographic-wrong-answers/

Now you can say look those are all implementation vulnerabilities,
it's not actually JWTs fault, I disagree. If I can find the same
vulnerability in five popular libraries, then maybe the spec did a
bad job of making sure people avoided that vulnerability.

So to completely head off the "it's just bad implementations"
argument, let's turn to the specs themselves: RFCs 7515, 7516, 7517,
7518, and 7519 are the core specifications that make up with is
commonly called "JWT" (and in RFC-land is more properly called "JOSE"
-- "JSON Object Signing and Encryption", of which the token format is
but one part).

The JOSE RFCs make a number of choices regarding default sets of
standardized cryptographic options. For example, RFC 7518 standardizes
thirteen signature algorithm options, seventeen encryption key
management options, and six different encryption cipher options.

This is already a problem -- that's an absolutely gigantic
combinatorial space of options! But then it gets worse.

Let's look just at the first table of options in that RFC, which is
for signing algorithms. It categorizes them as "Required",
"Recommended+", "Recommended", or "Optional". It then places into its
"Recommended" category options like RSASSA-PKCS-v1_5, which was known
to be vulnerable to Bleichenbacher's attack nine years before this RFC
was written (and Bleichenbacher's attack on PKCS#1 in general had been
known for 17 years at that point).

And then if we read a bit further we find ECDSA with P-256 is in the
"Recommended+" category, which the RFC helpfully says means that it is
likely to be bumped up to "Required" in the future. The P-256 curve
is... controversial, to say the least, and it took several additional
years before RFC 8037 finally standardized a better alternative
(Ed25519).

And that's just one quick glance at one table of one set of the
available options in one of the five core RFCs.

Here's another set of critical vulnerabilities:

https://blogs.adobe.com/security/2017/03/critical-vulnerability-uncovered-in-json-encryption.html

Five different libraries, for three different languages (and a
*different* set of libraries and languages than the previous
critical-vulnerability post I linked), all vulnerable to the same
basic invalid-curve attack.

Here's another one from just ten days ago:

https://insomniasec.com/blog/auth0-jwt-validation-bypass

Auth0's JWT validation was tricked into accepting unsigned tokens
thanks to a bug in parsing the (attacker-provided and
attacker-selected!) "alg" header parameter.

I could go on with this, but the general idea I'm trying to get across
is: JWT's issues are not just due to specific implementations being
bad. Several are issues that come with JWT itself, and are baked into
its design and specifications. The existence of vulnerabilities in
popular libraries is thus an expected consequence; no amount of
brilliance on the part of library authors can correct for the inherent
problems with JWT.

Meanwhile, we have access to alternatives that are simpler, more
robust, or often both. Django already supports at least two of them
out-of-the-box. As a result, I remain *strongly* against implementing
support for JWTs in Django, in any form, even the draft subset
implementation Claude has posted.

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAL13Cg8FkiPVi8oCuxtBUsiDoOUezXa%2B%2Bv5b75QxcZoDUtxy7A%40mail.gmail.com.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/873A28BE-2B12-48F6-9B94-B23AB4A798B4%40tomforb.es.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Steven Mapes
In reply to this post by James Bennett
I completely agree with James. I felt dread when I saw a JWT Thread appear as, for me synonymous with flaws security and I'd rather Django stay well clear of them

On Monday, 27 April 2020 03:53:39 UTC+1, James Bennett wrote:
On Sun, Apr 26, 2020 at 8:46 AM Adam Johnson <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="Rep92xfsAwAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">m...@...> wrote:
>
> James, I too would like to know your criticisms! I've always understood that they aren't much different to signed cookies, but I haven't looked too deeply at them.

Well, people asked. So.

The short summary is: JWT is over-complex, puts too much power in the
attacker's hands, has too many configuration knobs, and makes poor
cryptographic choices. This is why we see vulnerabilities in JWT
libraries and JWT-using systems again and again and again.

And even if you get every single bit of it right, in the ideal perfect
world with the ideal perfect implementation, the payoff is you've put
in a ton of work to get something that already existed: signed
cookies, for the use case of session identification, or any of several
better token or token-like systems -- everything from PASETO to just
timestamped HMAC'd values -- for the use case of inter-service
communication.

The longer version goes more like this...

JWT is a more complex thing than many people appreciate. In fact, it's
at least *five* things, each specified in its own RFC, plus some more
you have to know about and implement if you want any hope of getting
the actually-sorta-secure version. And right off the bat, that's
worrying: the more different things you have to implement, and the
more places you have to look to find out what and how to implement,
the more opportunities there are to make mistakes.

This complexity comes from the sheer number of different options JWT
tries to support, which in turn is an anti-pattern. JWTs may be
signed, or they may not. They may be encrypted, or they may not. There
are multiple different options for how to sign, how to encrypt, how to
manage and specify keys... in a well-designed system there would be
far fewer options. Ideally, there'd be only one option, and the
solution for a vulnerability being found in it would be to increment
the version of the underlying spec, and change to something
better.

Anyway. In JWT, signature and encryption schemes are effectively
negotiable, which is yet another anti-pattern: you are putting
enormous power in the hands of attackers to negotiate you down to a
bad, or nonexistent, cipher/algorithm for encryption or signing. TLS/SSL
learned this lesson the hard way; JWT has chosen not to learn it at
all. Worse, JWT embeds the negotiation about how to handle the token
into the token itself. This is just asking for trouble, and in fact
trouble has routinely occurred. As a somewhat sarcastic author of my
acquaintance put it:

> It is extraordinarily easy to screw up JWT. JWT is a JSON format
> where you have to parse and interpret a JSON document to figure out
> how to decrypt and authenticate a JSON document. It has revived bugs
> we thought long dead, like “repurposing asymmetric public keys as
> symmetric private keys”.

(from: <a href="https://latacora.micro.blog/a-childs-garden/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Flatacora.micro.blog%2Fa-childs-garden%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHpn7MLBSTdSGCgJWj1Mc5P1IkYJQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Flatacora.micro.blog%2Fa-childs-garden%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHpn7MLBSTdSGCgJWj1Mc5P1IkYJQ&#39;;return true;">https://latacora.micro.blog/a-childs-garden/)

More succinctly: JWTs inherently and unavoidably violate the
Cryptographic Doom Principle
(<a href="https://moxie.org/blog/the-cryptographic-doom-principle/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fmoxie.org%2Fblog%2Fthe-cryptographic-doom-principle%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNE-fao9mjuadpwatdojdAByZp_P_g&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fmoxie.org%2Fblog%2Fthe-cryptographic-doom-principle%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNE-fao9mjuadpwatdojdAByZp_P_g&#39;;return true;">https://moxie.org/blog/the-cryptographic-doom-principle/). Worse,
JWTs put full control of the violation in the hands of the attacker,
who -- thanks to the high level of configurability JWT offers -- is
free to find the set of options most likely to compromise you, and
foist them on you.

That quoted line above about revived long-dead bugs is no joke,
incidentally. Here's one from a few years back:

<a href="https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fauth0.com%2Fblog%2Fcritical-vulnerabilities-in-json-web-token-libraries%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEhGy5qq-UgmlOlOcCWe47qloHitw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fauth0.com%2Fblog%2Fcritical-vulnerabilities-in-json-web-token-libraries%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEhGy5qq-UgmlOlOcCWe47qloHitw&#39;;return true;">https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/

Five different libraries, written in three different languages, all
had the same bug. I once had the misfortune of arguing with someone
who attributed this to the libraries being built by bad programmers,
or in bad languages. But I personally tend to agree with a line from
this talk:

<a href="https://www.okta.com/video/oktane19-cryptographic-wrong-answers/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.okta.com%2Fvideo%2Foktane19-cryptographic-wrong-answers%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFSdm-kE1PdMofAVmG1-gcN2nqlvw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.okta.com%2Fvideo%2Foktane19-cryptographic-wrong-answers%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFSdm-kE1PdMofAVmG1-gcN2nqlvw&#39;;return true;">https://www.okta.com/video/oktane19-cryptographic-wrong-answers/

> Now you can say look those are all implementation vulnerabilities,
> it's not actually JWTs fault, I disagree. If I can find the same
> vulnerability in five popular libraries, then maybe the spec did a
> bad job of making sure people avoided that vulnerability.

So to completely head off the "it's just bad implementations"
argument, let's turn to the specs themselves: RFCs 7515, 7516, 7517,
7518, and 7519 are the core specifications that make up with is
commonly called "JWT" (and in RFC-land is more properly called "JOSE"
-- "JSON Object Signing and Encryption", of which the token format is
but one part).

The JOSE RFCs make a number of choices regarding default sets of
standardized cryptographic options. For example, RFC 7518 standardizes
thirteen signature algorithm options, seventeen encryption key
management options, and six different encryption cipher options.

This is already a problem -- that's an absolutely gigantic
combinatorial space of options! But then it gets worse.

Let's look just at the first table of options in that RFC, which is
for signing algorithms. It categorizes them as "Required",
"Recommended+", "Recommended", or "Optional". It then places into its
"Recommended" category options like RSASSA-PKCS-v1_5, which was known
to be vulnerable to Bleichenbacher's attack nine years before this RFC
was written (and Bleichenbacher's attack on PKCS#1 in general had been
known for 17 years at that point).

And then if we read a bit further we find ECDSA with P-256 is in the
"Recommended+" category, which the RFC helpfully says means that it is
likely to be bumped up to "Required" in the future. The P-256 curve
is... controversial, to say the least, and it took several additional
years before RFC 8037 finally standardized a better alternative
(Ed25519).

And that's just one quick glance at one table of one set of the
available options in one of the five core RFCs.

Here's another set of critical vulnerabilities:

<a href="https://blogs.adobe.com/security/2017/03/critical-vulnerability-uncovered-in-json-encryption.html" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fblogs.adobe.com%2Fsecurity%2F2017%2F03%2Fcritical-vulnerability-uncovered-in-json-encryption.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH6yFOVMDqWr-F5zOy72pSOJg5k5w&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fblogs.adobe.com%2Fsecurity%2F2017%2F03%2Fcritical-vulnerability-uncovered-in-json-encryption.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH6yFOVMDqWr-F5zOy72pSOJg5k5w&#39;;return true;">https://blogs.adobe.com/security/2017/03/critical-vulnerability-uncovered-in-json-encryption.html

Five different libraries, for three different languages (and a
*different* set of libraries and languages than the previous
critical-vulnerability post I linked), all vulnerable to the same
basic invalid-curve attack.

Here's another one from just ten days ago:

<a href="https://insomniasec.com/blog/auth0-jwt-validation-bypass" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Finsomniasec.com%2Fblog%2Fauth0-jwt-validation-bypass\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGe4fZR6mbMM_JoHqQjrskznvzxaA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Finsomniasec.com%2Fblog%2Fauth0-jwt-validation-bypass\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGe4fZR6mbMM_JoHqQjrskznvzxaA&#39;;return true;">https://insomniasec.com/blog/auth0-jwt-validation-bypass

Auth0's JWT validation was tricked into accepting unsigned tokens
thanks to a bug in parsing the (attacker-provided and
attacker-selected!) "alg" header parameter.

I could go on with this, but the general idea I'm trying to get across
is: JWT's issues are not just due to specific implementations being
bad. Several are issues that come with JWT itself, and are baked into
its design and specifications. The existence of vulnerabilities in
popular libraries is thus an expected consequence; no amount of
brilliance on the part of library authors can correct for the inherent
problems with JWT.

Meanwhile, we have access to alternatives that are simpler, more
robust, or often both. Django already supports at least two of them
out-of-the-box. As a result, I remain *strongly* against implementing
support for JWTs in Django, in any form, even the draft subset
implementation Claude has posted.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/87a3cf2c-bb9b-4575-bf98-ad255fdc96d0%40googlegroups.com.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Adam Johnson-2
Thank you very much James. I've learned once again that "everyone is using it" does not make it good.

(Would love if you pasted your write up on your blog to make it easier to share)

On Mon, 27 Apr 2020 at 10:37, Steven Mapes <[hidden email]> wrote:
I completely agree with James. I felt dread when I saw a JWT Thread appear as, for me synonymous with flaws security and I'd rather Django stay well clear of them

On Monday, 27 April 2020 03:53:39 UTC+1, James Bennett wrote:
On Sun, Apr 26, 2020 at 8:46 AM Adam Johnson <[hidden email]> wrote:
>
> James, I too would like to know your criticisms! I've always understood that they aren't much different to signed cookies, but I haven't looked too deeply at them.

Well, people asked. So.

The short summary is: JWT is over-complex, puts too much power in the
attacker's hands, has too many configuration knobs, and makes poor
cryptographic choices. This is why we see vulnerabilities in JWT
libraries and JWT-using systems again and again and again.

And even if you get every single bit of it right, in the ideal perfect
world with the ideal perfect implementation, the payoff is you've put
in a ton of work to get something that already existed: signed
cookies, for the use case of session identification, or any of several
better token or token-like systems -- everything from PASETO to just
timestamped HMAC'd values -- for the use case of inter-service
communication.

The longer version goes more like this...

JWT is a more complex thing than many people appreciate. In fact, it's
at least *five* things, each specified in its own RFC, plus some more
you have to know about and implement if you want any hope of getting
the actually-sorta-secure version. And right off the bat, that's
worrying: the more different things you have to implement, and the
more places you have to look to find out what and how to implement,
the more opportunities there are to make mistakes.

This complexity comes from the sheer number of different options JWT
tries to support, which in turn is an anti-pattern. JWTs may be
signed, or they may not. They may be encrypted, or they may not. There
are multiple different options for how to sign, how to encrypt, how to
manage and specify keys... in a well-designed system there would be
far fewer options. Ideally, there'd be only one option, and the
solution for a vulnerability being found in it would be to increment
the version of the underlying spec, and change to something
better.

Anyway. In JWT, signature and encryption schemes are effectively
negotiable, which is yet another anti-pattern: you are putting
enormous power in the hands of attackers to negotiate you down to a
bad, or nonexistent, cipher/algorithm for encryption or signing. TLS/SSL
learned this lesson the hard way; JWT has chosen not to learn it at
all. Worse, JWT embeds the negotiation about how to handle the token
into the token itself. This is just asking for trouble, and in fact
trouble has routinely occurred. As a somewhat sarcastic author of my
acquaintance put it:

> It is extraordinarily easy to screw up JWT. JWT is a JSON format
> where you have to parse and interpret a JSON document to figure out
> how to decrypt and authenticate a JSON document. It has revived bugs
> we thought long dead, like “repurposing asymmetric public keys as
> symmetric private keys”.

(from: https://latacora.micro.blog/a-childs-garden/)

More succinctly: JWTs inherently and unavoidably violate the
Cryptographic Doom Principle
(https://moxie.org/blog/the-cryptographic-doom-principle/). Worse,
JWTs put full control of the violation in the hands of the attacker,
who -- thanks to the high level of configurability JWT offers -- is
free to find the set of options most likely to compromise you, and
foist them on you.

That quoted line above about revived long-dead bugs is no joke,
incidentally. Here's one from a few years back:

https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/

Five different libraries, written in three different languages, all
had the same bug. I once had the misfortune of arguing with someone
who attributed this to the libraries being built by bad programmers,
or in bad languages. But I personally tend to agree with a line from
this talk:

https://www.okta.com/video/oktane19-cryptographic-wrong-answers/

> Now you can say look those are all implementation vulnerabilities,
> it's not actually JWTs fault, I disagree. If I can find the same
> vulnerability in five popular libraries, then maybe the spec did a
> bad job of making sure people avoided that vulnerability.

So to completely head off the "it's just bad implementations"
argument, let's turn to the specs themselves: RFCs 7515, 7516, 7517,
7518, and 7519 are the core specifications that make up with is
commonly called "JWT" (and in RFC-land is more properly called "JOSE"
-- "JSON Object Signing and Encryption", of which the token format is
but one part).

The JOSE RFCs make a number of choices regarding default sets of
standardized cryptographic options. For example, RFC 7518 standardizes
thirteen signature algorithm options, seventeen encryption key
management options, and six different encryption cipher options.

This is already a problem -- that's an absolutely gigantic
combinatorial space of options! But then it gets worse.

Let's look just at the first table of options in that RFC, which is
for signing algorithms. It categorizes them as "Required",
"Recommended+", "Recommended", or "Optional". It then places into its
"Recommended" category options like RSASSA-PKCS-v1_5, which was known
to be vulnerable to Bleichenbacher's attack nine years before this RFC
was written (and Bleichenbacher's attack on PKCS#1 in general had been
known for 17 years at that point).

And then if we read a bit further we find ECDSA with P-256 is in the
"Recommended+" category, which the RFC helpfully says means that it is
likely to be bumped up to "Required" in the future. The P-256 curve
is... controversial, to say the least, and it took several additional
years before RFC 8037 finally standardized a better alternative
(Ed25519).

And that's just one quick glance at one table of one set of the
available options in one of the five core RFCs.

Here's another set of critical vulnerabilities:

https://blogs.adobe.com/security/2017/03/critical-vulnerability-uncovered-in-json-encryption.html

Five different libraries, for three different languages (and a
*different* set of libraries and languages than the previous
critical-vulnerability post I linked), all vulnerable to the same
basic invalid-curve attack.

Here's another one from just ten days ago:

https://insomniasec.com/blog/auth0-jwt-validation-bypass

Auth0's JWT validation was tricked into accepting unsigned tokens
thanks to a bug in parsing the (attacker-provided and
attacker-selected!) "alg" header parameter.

I could go on with this, but the general idea I'm trying to get across
is: JWT's issues are not just due to specific implementations being
bad. Several are issues that come with JWT itself, and are baked into
its design and specifications. The existence of vulnerabilities in
popular libraries is thus an expected consequence; no amount of
brilliance on the part of library authors can correct for the inherent
problems with JWT.

Meanwhile, we have access to alternatives that are simpler, more
robust, or often both. Django already supports at least two of them
out-of-the-box. As a result, I remain *strongly* against implementing
support for JWTs in Django, in any form, even the draft subset
implementation Claude has posted.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/87a3cf2c-bb9b-4575-bf98-ad255fdc96d0%40googlegroups.com.


--
Adam

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAMyDDM3bOGqxEM3Nc8yh3uK%3DFmrcuZJy3Lgci91dnZNbr%3DXuYQ%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Derek Adair
In reply to this post by Tom Forbes
Maybe we can update the docs to show how you you would might use some of the signing primitives instead of JWTs, but this also sounds a bit dangerous 🤷‍♂️ 

As someone hoodwinked into believing JWT was the way... I'd absolutely LOVE a clear and concise write up on how I might get my single page js apps to communicate securely with projects like Django Rest. 

Thanks for closing the door on JWT for me James.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/adc7a8eb-6100-4639-af98-4bca9afaad0b%40googlegroups.com.
Reply | Threaded
Open this post in threaded view
|

Re: Generate JWTs with Django

Dan Davis
The place where JWT begins to get useful and important is when federated login capabilities end-up in your app. That sort of thing seems more the domain of python-social-auth packages like social-auth-core and social-auth-app-django.  Generating an authentication cookie doesn't require JWT - Django already does that.

On Mon, May 11, 2020 at 9:37 AM Derek Adair <[hidden email]> wrote:
Maybe we can update the docs to show how you you would might use some of the signing primitives instead of JWTs, but this also sounds a bit dangerous 🤷‍♂️ 

As someone hoodwinked into believing JWT was the way... I'd absolutely LOVE a clear and concise write up on how I might get my single page js apps to communicate securely with projects like Django Rest. 

Thanks for closing the door on JWT for me James.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/adc7a8eb-6100-4639-af98-4bca9afaad0b%40googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAFzonYarnig9vCJAekv%3DsaKuMJ-jz755XgLd%2B4GKJ0cN5YSBnQ%40mail.gmail.com.