JSON Web Token Best Current Practices

Summary: Has a DISCUSS. Has enough positions to pass once DISCUSS positions are resolved.

Benjamin Kaduk Discuss

Discuss (2019-06-24)
Thank you for assembling this document; it will be very valuable to the
community.  I intend to ballot Yes once the following items are

Section 2.6 notes:
   Previous versions of the JSON format such as the obsoleted [RFC7159]
   allowed several different character encodings: UTF-8, UTF-16 and UTF-
   32.  This is not the case anymore, with the latest standard [RFC8259]
   only allowing UTF-8.  [...]

The actual situation is a bit more subtle than this text makes it seem;
interoperable JSON can only use non-UTF-8 with explicit mutual
prearrangement in a closed ecosystem.  So, while this statement is true
for Internet JWT usage, it may not be true for *all* JWT usage.
(I do see that in Section 3.7 of this document we do mandate UTF-8 for
JWT, which makes things unambiguous, even if this text here is not

Section 3.2 notes:
   JWT libraries SHOULD NOT generate JWTs using "none" unless explicitly
   requested to do by the caller.

I couldn't find anywhere where we have matching guidance about "SHOULD
NOT consume JWTs using 'none' unless explicitly requested"; this seems
important enough to get called out explicitly.
Comment (2019-06-24)
I also have some non-Discuss-level substantive comments in the section-by-section notes,
in addition to the usual editorial nits.

Section 1

   and/or encrypted.  The JWT specification has seen rapid adoption
   because it encapsulates security-relevant information in one, easy to
   protect location, and because it is easy to implement using widely-

nit: "one easy-to-protect location".

Section 2.2

I'd consider rewording the text here to make it more poignant; perhaps:

  In addition, some applications use a keyed MAC algorithm such as
  "HS256" to sign tokens, but supply a weak symmetric key with
  insufficient entropy (such as a human memorable password).  Such keys
  are vulnerable to offline brute-force or dictionary attacks once an
  attacker possesses such a token.

Section 2.4

I'd suggest noting that the compression attacks are particularly
powerful when there is attacker-controlled data in the same compression
space as secret data.

Section 3.2

   Therefore, applications MUST only allow the use of cryptographically
   current algorithms that meet the security requirements of the
   application.  This set will vary over time as new algorithms are
   introduced and existing algorithms are deprecated due to discovered
   cryptographic weaknesses.  Applications MUST therefore be designed to
   enable cryptographic agility.

This seems to have high overlap with BCP 201; a reference is probably in

Section 3.4

   Some cryptographic operations, such as Elliptic Curve Diffie-Hellman
   key agreement ("ECDH-ES") take inputs that may contain invalid
   values, such as points not on the specified elliptic curve or other
   invalid points (see e.g.  [Valenta], Sec. 7.1).  Either the JWS/JWE
   library itself must validate these inputs before using them or it
   must use underlying cryptographic libraries that do so (or both!).

side note: A phrasing like "JWS/JWE libraries MUST ensure that such
input validation occurs" would leave the same wiggle room for the
validation to occur at the underlying crypto layer, while leaving it
crystal clear what entity is responsible for ensuring that the checks
occur".  But since I don't expect a change of this nature to actually
cause different behavior by implementors, I'm not very tied to it.

Section 3.8

When we say "[o]ther applications may use different means of binding
keys to issuers", is there any value in noting that certification by a
trusted authority is a common way to perform this binding (in some

Section 3.9

   If the same issuer can issue JWTs that are intended for use by more
   than one relying party or application, the JWT MUST contain an "aud"
   (audience) claim that can be used to determine whether the JWT is
   being used by an intended party or was substituted by an attacker at
   an unintended party.  Furthermore, the relying party or application
   MUST validate the audience value and if the audience value is not
   present or not associated with the recipient, it MUST reject the JWT.

(grammar nit?) Is the "Furthermore" sentence supposed to still be scoped
to the case where the issuer can issue JWTs for more than one audience?
If not, it seems like we're requiring the rejection of all "aud"-less
JWTs but not requiring "aud" to be present when generating them.

Section 3.10

                                                Applications should
   protect against such attacks, e.g., by matching the URL to a
   whitelist of allowed locations, and ensuring no cookies are sent in
   the GET request.

This could probably be a SHOULD (or even a MUST?).

Section 3.11

   When applying explicit typing to a Nested JWT, the "typ" header
   parameter containing the explicit type value MUST be present in the
   inner JWT of the Nested JWT (the JWT whose payload is the JWT Claims
   Set).  The same "typ" header parameter value MAY be present in the
   outer JWT as well, to explicitly type the entire Nested JWT.

This is an interesting recommendation, as it is in some sense
*introducing* type confusion by using the same type name for JWTs with
different structures (the inner and outer JWTs)!  My sense is that it is
not practical to change current usage, though, so I think this should be
treated as a side note and not an actionable recommendation.

Section 3.12

   -  Use different keys for different kinds of JWTs.  Then the keys
      used to validate one kind of JWT will fail to validate other kinds
      of JWTs.

It might be worth calling back an analogy to RFC 8037's security
considerations (where we advise to keep an association between key
material and key algorithm), in effect extending the scope of
"algorithm" to include application usage.

   Given the broad diversity of JWT usage and applications, the best
   combination of types, required claims, values, header parameters, key
   usages, and issuers to differentiate among different kinds of JWTs
   will, in general, be application specific.  For new JWT applications,
   the use of explicit typing is RECOMMENDED.

This last recommendation seems to duplicate one from the end of Section
3.11.  While it's important and worth reiterating, we do usually try to
avoiding using normative RFC 2119 language when repeating ourselves, to
make it very clear which requirement is the binding one.

Alissa Cooper Yes

Comment (2019-06-24)
= Section 1 =

 Many of the recommendations in this document
   will actually be about implementation and use of the cryptographic
   mechanisms underlying JWTs that are defined by JSON Web Signature
   (JWS) [RFC7515], JSON Web Encryption (JWE) [RFC7516], and JSON Web
   Algorithms (JWA) [RFC7518].  Others will be about use of the JWT
   claims themselves.

s/will actually be/are/
s/will be/are/

= Section 3.12 =

Are all of the recommended strategies listed targeted at application developers specifically? It might be useful to note that if so.

Roman Danyliw Yes

Barry Leiba Yes

Comment (2019-06-24)
Nice work on this; thanks.

-- Section 1 --

   Readers are advised to seek out any errata or updates that apply to this document.

Excellent.  I note that this is a really nice opportunity to include, here, a URI to a page in the working group wiki or github that you can now create and that will be used to post updates (that might not qualify as errata) before they're incorporated into published updates.

Other than that,  I just have some editorial comments:

-- Section 1.1 --

   -  Implementers of JWT libraries (and the JWS and JWE libraries used
      by them),

Nit: Does "them" refer to the implementers or the libraries?  Please re-phrase to clarify.

-- Section 2.4 --

Nit: "and thus, the ciphertext, depends" should be "and, thus, the ciphertext depend" (note moved comma and plural verb).

-- Section 2.6 --

Nit: "However older implementations" needs a comma: "However, older implementations"

-- Section 2.7 --
I find the paragraph to be somewhat awkward, and suggest a slight rewording, thus:

There are attacks in which one recipient will be given a JWT that was intended for it, and will attempt to use it at a different recipient for which that JWT was not intended.  For instance, if an OAuth 2.0 [RFC6749] access token is legitimately presented to an OAuth 2.0 protected resource which it is intended, that protected resource might then present that same access token to different protected resource for which the access token is not intended, in an attempt to gain access.  If such situations are not caught, this can result in the attacker gaining access to resources that it is not entitled to access.

As to the title of this section, this doesn't seem to be a "substitution".  I'm not sure what to call it (maybe it's a form of replay attack, but maybe not really), but "substitution" doesn't seem right.

-- Section 2.9 --

Nit: In "operations, e.g. database and LDAP searches," you need a comma after "e.g."  Or, better still, just change "e.g." to "such as", and avoid the Latin.

-- Section 3.4 --

Nit: "(see e.g.  [Valenta], Sec. 7.1)" needs commas: "(see, e.g.,  [Valenta], Sec. 7.1)"  And in the next sentence, because of the "or both!" at the end I would remove the "Either" at the beginning.

-- Section 3.6 --

   It is RECOMMENDED to avoid any compression of data before encryption
   since such compression often reveals information about the plaintext.

The passive voice doesn't work in this construct; "it is recommended to avoid" doesn't seem like proper English.  Also, it's not the compression that reveals information, but the resultant compressed data, right?  How about this?:

   Compression of data SHOULD NOT be done before encryption, because
   such compressed data often reveals information about the plaintext.

-- Section 3.11 --

   Confusion of one kind of JWT for another can be prevented by having
   all the kinds of JWTs that could otherwise potentially be confused
   include an explicit JWT type value and include checking the type
   value in their validation rules.

I find the sentence awkward, and suggest a slight rewrite:

   Sometimes, one kind of JWT can be confused for another.  If a particular
   kind of JWT is subject to such confusion, that JWP can include an explicit
   JWT type value, and the validation rules can specify checking the type.
   This mechanism can prevent such confusion.

Deborah Brungard No Objection

Suresh Krishnan No Objection

Warren Kumari No Objection

Mirja Kühlewind No Objection

Comment (2019-06-25)
I'm by far no expert here but I don't really understand all attacks described. Maybe it's just me, however, especially 2.7 and 2.8 seem quite high level to me and I'm wondering if it is possible to be more concrete or provide an example or something. Anyway, the more important part is section 3, so no need to worry too much about this.

I'm wondering if it would make sense for this document to update RFC7519. I know there is no direct change but it complements RFC7519 and using the update mechanism makes I easy/easier for readers of RFC7519 two find this doc.

Alvaro Retana No Objection

Adam Roach (was Discuss) No Objection

Comment (2019-06-24)

>  That said, if a JWT is cryptographically protected by a transport
>  layer, such as TLS using cryptographically current algorithms, there
>  may be no need to apply another layer of cryptographic protections to
>  the JWT.

It may be helpful to distinguish between end-to-end TLS encryption (such as that
seen in HTTPS, even in the presence of proxies) and hop-by-hop TLS encryption
(such as that seen in SIPS when proxies are present). In the latter case,
intermediaries may perform attacks that would otherwise only be possible to
mount by the endpoints.

My concrete suggestion is to modify the above text to read "...protected
end-to-end by a transport layer, such as..."



>  -  Avoid all RSA-PKCS1 v1.5 [RFC2313] encryption algorithms,
>     preferring RSA-OAEP ([RFC8017], Sec. 7.1).

It's not clear to me what this recommendation intends to say regarding the
algorithms in RFC 2437 and RFC 3447. One might infer that they're deprecated
as well. If this is the intention, please be explicit.

Martin Vigoureux No Objection

Comment (2019-06-26)
Hello, thank you for this document.

I wonder whether [nist-sp-800-56a-r3] should be a normative reference.


Éric Vyncke No Objection

Comment (2019-06-27)
Thank you all for the work put into this document. I have only one NIT

== NITS ==

-- Section 1.1 --

s/The targets of this document are/The intended audience of this document are/

Magnus Westerlund No Objection

Ignas Bagdonas No Record

Alexey Melnikov No Record