Hi Yaron,
The title of this document is JSON Web Token Best Current Practices.
Its goal is "to provide actionable guidance leading to secure
implementation and deployment of JWTs" and
"to facilitate *secure implementation* and deployment of JWTs"
(Introduction).
Section 2 (Threats and Vulnerabilities) lists some known and possible
problems with JWT implementations and deployments.
Section 2.7 (Substitution Attacks) states:
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.
This relates to the audience of the JWT.
Section 2.8 (Cross-JWT Confusion) states:
As JWTs are being used by more different protocols in diverse
application areas, it becomes increasingly important to prevent
cases of JWT tokens that have been issued for one purpose being
subverted and used for another.
The concept of "purpose" is inexistent in JWT-SD and would need to be
clarified.
This draft is concentrating on the structure of JWTs, but is ignoring
the context in which JWTs are requested, obtained and then used.
SD-JWTs defined SD-JWTs *formats* for two flows:
a) when an issuer issues a SD-JWT including all Disclosures,
b) when a verifier presents SD-JWT or SD-JWT+KB including selected
Disclosures.
However, SD-JWT does not define which *protocols* can be used to carry
these data formats.
Hence, threats and vulnerabilities that can arise in these protocols are
not considered, nor addressed.
This means that the current content of this draft while explicit
targeted to "Developers of specifications that rely on JWTs, both inside
and outside the IETF" is incomplete.
Two important "specifications that rely on JWTs *outside the IETF*" are:
"OID4VCI": OpenID for Verifiable Credential Issuance - draft 16
https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html
"OID4VP": "OpenID for Verifiable Presentations 1.0" which defines a
protocol for requesting and presenting Credentials (published on 9
July 2025).
It defines a mechanism on top of OAuth 2.0 to allow presentation of
claims in the form of Verifiable Credentials as part of the protocol
flow.
https://openid.net/specs/openid-4-verifiable-presentations-1_0.html
These two OpenID specifications contain many optional features. This
makes difficult for implementers to select a right combination that
allows to develop a secure implementation.
When using selective disclosure of claims, it is important to prevent
cases where JWTs issued for one individual would be usable by another
individual with a complicity
between these individuals. In some cases, this issue is identified as a
"relay attack".
This issue has not been identified in the documents produced by the
OAuth WG (nor the SPICE WG), nor in OID4VP.
OID4VP defines protocols for requesting and presenting Credentials. It
is not explicitly said that these protocols must be supported by a
single application and
that the end-user using the device supporting that application SHALL NOT
be able to modify it or to use its "key store" by downloading a rogue
application and
then using these keys with it.
Once this issue is identified, it needs to be addressed in a section
called "implementation considerations" which, unfortunately, is
inexistent in the proposed draft.
This topic is highly dependent upon the type of the device, however,
general considerations apply.
Denis
PS: I have created an issue with the same text at:
https://github.com/yaronf/draft-sheffer-oauth-rfc8725bis/issues/15
Thank you Dan for a very thorough review. Since everybody’s busy ahead
of IETF week, I just piled everything into a GitHub issue for now:
https://github.com/yaronf/draft-sheffer-oauth-rfc8725bis/issues/14
Best,
Yaron
*From: *Dan Moore <d...@fusionauth.io>
*Date: *Monday, 14 July 2025 at 20:52
*To: *Yaron Sheffer <yaronf.i...@gmail.com>
*Cc: *oauth@ietf.org <oauth@ietf.org>
*Subject: *Re: [OAUTH-WG] FW: New Version Notification for
draft-sheffer-oauth-rfc8725bis-01.txt
Hi Yaron,
Had some comments and formatting suggestions. I also found a broken link.
Overall I found this a great summary of the JWT best practices I've
seen in the wild and look forward to referring people to this doc.
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#name-weak-symmetric-keys
perhaps you want to mention this open source project which cracks JWTs
signed with a weak HMAC key: https://github.com/brendan-rius/c-jwt-cracker
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#name-incorrect-use-and-compositi
I'd change
"However verifiers don't always check that the received JWT is a
signed JWS as opposed to an encrypted JWE structure."
to
"However verifiers don't always check that the received JWT is a JWS
(a signed JWT) as opposed to a JWE (a JWT with encrypted structure)."
A JWS is by definition signed, just as a JWE is by definition
encrypted, so I thought this was clearer.
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-2.4
I'd change
"Many encryption algorithms leak information about the length of the
plaintext, with a varying amount of leakage depending on the algorithm
and mode of operation."
to
"Many encryption algorithms leak information about the length of the
plaintext, with a varying amount of leakage depending on the algorithm
and mode of operation. JWEs are vulnerable to this leakage."
Alternatively you could add other language to make it clear this
attack is applicable to JWEs, not JWTs in general, just as is done in
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-2.12
. I suppose you could even change the section header to "JWE Plaintext
Leakage through Analysis of Ciphertext Length". In general there are a
few security issues that are related to encryption and therefore only
affect JWEs.
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-2.5
The Sanso link is busted (expired cert, 404 for
https://blogs.adobe.com/security/2017/03/critical-vulnerability-uncovered-in-json-encryption.html
) so you might want to review.
Is the attack outlined here
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-2.5
the same as
https://neilmadden.blog/2022/04/19/psychic-signatures-in-java/ ? If
so, maybe that is a better link?
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-2.8
I'd change
"As JWTs are being used by more different protocols in diverse
application areas, it becomes increasingly important to prevent cases
of JWT tokens that have been issued for one purpose being subverted
and used for another."
To
"As JWTs are used by more protocols in diverse ways, it becomes
increasingly important to prevent JWT tokens that have been issued for
one purpose being used for another."
Just think it reads cleaner.
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-3.1-2
I'd change
"In particular, use allowlists for critical parameters such as "alg"
instead of blocklists."
"In particular, libraries SHOULD use allowlists for critical
parameters such as "alg" instead of blocklists."
This makes it a complete sentence.
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-3.2
you quote the RFC which mentions SHOULD but then you follow it up with
MUST. I find that confusing. I'd remove the first paragraph or at
least this sentence: "Even if a JWS can be successfully validated,
unless the algorithm(s) used in the JWS are acceptable to the
application, it SHOULD consider the JWS to be invalid." because then
you remove the SHOULD/MUST confusion I had.
In that same section, the semi-colon was awkward. I'd change
"JWTs using "none" are often used in application contexts in which the
content is optionally signed; then, the URL-safe claims representation
and processing can be the same in both the signed and unsigned cases."
to
"JWTs using "none" are often used in application contexts in which the
content is optionally signed. The URL-safe claims representation and
processing in this context can be the same in both the signed and
unsigned cases."
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-3.3
I'd change
"Libraries MUST allow the verifier to distinguish between JWS-signed
and JWE-encrypted JWTs. This would allow verifiers to easily establish
a policy of only accepting JWS-signed JWTs."
to
"Libraries MUST allow the verifier to distinguish between signed JWTs
(JWSes) and encrypted JWTs (JWEs). This allows verifiers to easily
establish a policy of only accepting signed JWTs."
I found the terms JWS-signed and JWT-encrypted confusing. They felt
internally redundant (a JWS is always signed, for example).
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-3.6
I wondered if it made sense to mention JWEs here? Maybe change
"Compression of data SHOULD NOT be done before encryption, because
such compressed data often reveals information about the plaintext."
to
"Compression of data SHOULD NOT be used when creating a JWE, because
such compressed data often reveals information about the plaintext."
This distinguishes between JWS and JWE, where the latter is the only
one this recommendation applies to.
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-3.7
I'd change
"Implementations and applications MUST do this and not use or admit
the use of other Unicode encodings for these purposes."
to
"Implementations and applications MUST do this and not use or allow
the use of other Unicode encodings for these purposes."
Unless "admit" means something special in this context, "allow" is
clearer. "allow" seems more common and "admit" is not used elsewhere
in this doc.
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-3.9
I worry about changes to the implementation (where you start with one
RP/app, then add more). I'd address this by adding a clause about the
future:
"If the same issuer can issue JWTs that are intended for use by more
than one relying party or application"
to
"If the same issuer can issue JWTs that are intended for use by more
than one relying party or application, or may in the future,"
I'd also change
"or was substituted by an attacker at an unintended party."
to
"or was substituted by an attacker."
I'm not sure what the "unintended party" phrase adds.
There's also this sentence:
"In such cases, 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."
The aud claim can be an array
https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3 . Should
we mention that here? Maybe something like:
"In such cases, the relying party or application MUST validate the
audience value, and if no audience value is present or none of the
values are associated with the recipient, it MUST reject the JWT."
I found
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-3.11-2
confusing. Here's the text:
"Per the definition of "typ" in Section 4.1.9 of [RFC7515], it is
RECOMMENDED that the "application/" prefix be omitted from the "typ"
value. Therefore, for example, the "typ" value used to explicitly
include a type for a SET SHOULD be "secevent+jwt". When explicit
typing is employed for a JWT, it is RECOMMENDED that a media type name
of the format "application/example+jwt" be used, where "example" is
replaced by the identifier for the specific kind of JWT."
As a JWT creator, should I be including "application/" in the typ
value? I see recommendations for and against that, unless the media
type name refers to something other than the value of the typ header.
What am I missing?
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-3.12
I missed the MUST here, as I jumped right to the list. I'd suggest a
small formatting change to highlight the MUST. Can we do a newline to
make it clearer? That would change:
"If more than one kind of JWT can be issued by the same issuer, the
validation rules for those JWTs MUST be written such that they are
mutually exclusive, rejecting JWTs of the wrong kind. To prevent
substitution of JWTs from one context into another, application
developers may employ a number of strategies:"
to
"If more than one kind of JWT can be issued by the same issuer, the
validation rules for those JWTs MUST be written such that they are
mutually exclusive, rejecting JWTs of the wrong kind.
To prevent substitution of JWTs from one context into another,
application developers may employ a number of strategies:"
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-3.13
that 600k OWASP iteration recommendation value changes over time. Do
you want this text to be more broadly applicable in the future? (Not
sure how this kind of thing is handled in general.) If so, could
change this from:
""[OWASP-Password-Storage] states that an iteration count of 600,000
is required when using HMAC-SHA-256 to achieve FIPS-140 compliance.
Thus, rejecting inputs with a p2c (PBES2 Count) value over 1,200,000
(double that) is RECOMMENDED."
to
"[OWASP-Password-Storage] states a specific iteration count (600,000
at time of publishing) is required when using HMAC-SHA-256 to achieve
FIPS-140 compliance. Rejecting inputs with a p2c (PBES2 Count) value
larger than double the recommended OWASP value is RECOMMENDED."
In
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html#section-3.14
it is unclear to me if this if this is for the JWT as encoded or the
decoded value? I think encoded, but am not sure. Do you want to
reference base64 url encoding here? as mentioned in 7515 and by
https://datatracker.ietf.org/doc/html/rfc4648#section-5
Thanks,
Dan
On Fri, May 23, 2025 at 4:18 AM Yaron Sheffer <yaronf.i...@gmail.com>
wrote:
Hi everyone,
RFC 8725 is the JWT Best Practices document that was published 5
years ago. Since then, several new vulnerabilities and
implementation issues were found, and this is a “bis” document to
inform the community of these issues and recommend mitigations.
This is a relatively small change to the existing BCP. We have
(almost) exhausted the issues we are aware of and we’re requesting
adoption by the working group. Once adopted, we believe we can
quickly move to WGLC.
Thanks,
Yaron, Mike and Dick
On 23/05/2025, 13:11, "internet-dra...@ietf.org"
<internet-dra...@ietf.org> wrote:
A new version of Internet-Draft
draft-sheffer-oauth-rfc8725bis-01.txt has been
successfully submitted by Yaron Sheffer and posted to the
IETF repository.
Name: draft-sheffer-oauth-rfc8725bis
Revision: 01
Title: JSON Web Token Best Current Practices
Date: 2025-05-23
Group: Individual Submission
Pages: 18
URL:
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.txt
Status:
https://datatracker.ietf.org/doc/draft-sheffer-oauth-rfc8725bis/
HTML:
https://www.ietf.org/archive/id/draft-sheffer-oauth-rfc8725bis-01.html
HTMLized:
https://datatracker.ietf.org/doc/html/draft-sheffer-oauth-rfc8725bis
Diff:
https://author-tools.ietf.org/iddiff?url2=draft-sheffer-oauth-rfc8725bis-01
Abstract:
JSON Web Tokens, also known as JWTs, are URL-safe JSON-based
security
tokens that contain a set of claims that can be signed and/or
encrypted. JWTs are being widely used and deployed as a simple
security token format in numerous protocols and applications,
both in
the area of digital identity and in other application areas. This
Best Current Practices document updates RFC 7519 to provide
actionable guidance leading to secure implementation and deployment
of JWTs.
The IETF Secretariat
_______________________________________________
OAuth mailing list -- oauth@ietf.org
To unsubscribe send an email to oauth-le...@ietf.org
_______________________________________________
OAuth mailing list --oauth@ietf.org
To unsubscribe send an email tooauth-le...@ietf.org
_______________________________________________
OAuth mailing list -- oauth@ietf.org
To unsubscribe send an email to oauth-le...@ietf.org