CVE-2020-15222
Replay of private_key_jwt possible in ORY Fosite
In ORY Fosite (the security first OAuth2 & OpenID Connect framework for Go) before version 0.31.0, when using "private_key_jwt" authentication the uniqueness of the jti value is not checked. When using client authentication method "private_key_jwt", OpenId specification says the following about assertion jti: "A unique identifier for the token, which can be used to prevent reuse of the token. These tokens MUST only be used once, unless conditions for reuse were negotiated between the parties". Hydra does not seem to check the uniqueness of this jti value. This problem is fixed in version 0.31.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Required
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
8.1
Replay of private_key_jwt possible in ORY Fosite
In ORY Fosite (the security first OAuth2 & OpenID Connect framework for Go) before version 0.31.0, when using "private_key_jwt" authentication the uniqueness of the jti value is not checked. When using client authentication method "private_key_jwt", OpenId specification says the following about assertion jti: "A unique identifier for the token, which can be used to prevent reuse of the token. These tokens MUST only be used once, unless conditions for reuse were negotiated between the parties". Hydra does not seem to check the uniqueness of this jti value. This problem is fixed in version 0.31.0.
- Record
CVE-2020-15222- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N - Weakness
- CWE-287
- Updated
- 2026-11-02
EUVDEUVD-2021-1195
8.1
In ORY Fosite (the security first OAuth2 & OpenID Connect framework for Go) before version 0.31.0, when using "private_key_jwt" authentication the uniqueness of the jti value is not checked. When using client authentication method "private_key_jwt", OpenId specification says the following about assertion jti: "A unique identifier for the token, which can be used to prevent reuse of the token. These tokens MUST only be used once, unless conditions for reuse were negotiated between the parties". Hydra does not seem to check the uniqueness of this jti value. This problem is fixed in version 0.31.0.
- Record
EUVD-2021-1195- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N - Updated
- 2026-11-03
GitHub AdvisoriesGHSA-v3q9-2p3m-7g43
8.1
Token reuse in Ory fosite
Impact
When using client authentication method "private_key_jwt" [1], OpenId specification says the following about assertion jti:
A unique identifier for the token, which can be used to prevent reuse of the token. These tokens MUST only be used once, unless conditions for reuse were negotiated between the parties
Hydra does not seem to check the uniqueness of this jti value. Here is me sending the same token request twice, hence with the same jti assertion, and getting two access tokens:
$ curl --insecure --location --request POST 'https://localhost/_/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=c001d00d-5ecc-beef-ca4e-b00b1e54a111' \
--data-urlencode 'scope=application openid' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
--data-urlencode 'client_assertion=eyJhb [...] jTw'
{"access_token":"zeG0NoqOtlACl8q5J6A-TIsNegQRRUzqLZaYrQtoBZQ.VR6iUcJQYp3u_j7pwvL7YtPqGhtyQe5OhnBE2KCp5pM","expires_in":3599,"scope":"application openid","token_type":"bearer"}⏎
$ curl --insecure --location --request POST 'https://localhost/_/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=c001d00d-5ecc-beef-ca4e-b00b1e54a111' \
--data-urlencode 'scope=application openid' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
--data-urlencode 'client_assertion=eyJhb [...] jTw'
{"access_token":"wOYtgCLxLXlELORrwZlmeiqqMQ4kRzV-STU2_Sollas.mwlQGCZWXN7G2IoegUe1P0Vw5iGoKrkOzOaplhMSjm4","expires_in":3599,"scope":"application openid","token_type":"bearer"}
Patches
This issue is patched in 0.31.0.
Workarounds
Do not allow clients to use private_key_jwt.
References
https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication
- Record
GHSA-v3q9-2p3m-7g43- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N - Weakness
- CWE-287, CWE-345
- Updated
- 2026-11-02
NVD
8.1
In ORY Fosite (the security first OAuth2 & OpenID Connect framework for Go) before version 0.31.0, when using "private_key_jwt" authentication the uniqueness of the jti value is not checked. When using client authentication method "private_key_jwt", OpenId specification says the following about assertion jti: "A unique identifier for the token, which can be used to prevent reuse of the token. These tokens MUST only be used once, unless conditions for reuse were negotiated between the parties". Hydra does not seem to check the uniqueness of this jti value. This problem is fixed in version 0.31.0.
- Record
CVE-2020-15222- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N - CVSS 2.0
- 5.8 Medium
AV:N/AC:M/Au:N/C:P/I:P/A:N - Weakness
- CWE-287, CWE-345
- Updated
- 2026-11-02
OSV
8.1
In ORY Fosite (the security first OAuth2 & OpenID Connect framework for Go) before version 0.31.0, when using "private_key_jwt" authentication the uniqueness of the jti value is not checked. When using client authentication method "private_key_jwt", OpenId specification says the following about assertion jti: "A unique identifier for the token, which can be used to prevent reuse of the token. These tokens MUST only be used once, unless conditions for reuse were negotiated between the parties". Hydra does not seem to check the uniqueness of this jti value. This problem is fixed in version 0.31.0.
- Record
CVE-2020-15222- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N - Updated
- 2026-11-02
OSVGHSA-v3q9-2p3m-7g43
8.1
Token reuse in Ory fosite
Impact
When using client authentication method "private_key_jwt" [1], OpenId specification says the following about assertion jti:
A unique identifier for the token, which can be used to prevent reuse of the token. These tokens MUST only be used once, unless conditions for reuse were negotiated between the parties
Hydra does not seem to check the uniqueness of this jti value. Here is me sending the same token request twice, hence with the same jti assertion, and getting two access tokens:
$ curl --insecure --location --request POST 'https://localhost/_/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=c001d00d-5ecc-beef-ca4e-b00b1e54a111' \
--data-urlencode 'scope=application openid' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
--data-urlencode 'client_assertion=eyJhb [...] jTw'
{"access_token":"zeG0NoqOtlACl8q5J6A-TIsNegQRRUzqLZaYrQtoBZQ.VR6iUcJQYp3u_j7pwvL7YtPqGhtyQe5OhnBE2KCp5pM","expires_in":3599,"scope":"application openid","token_type":"bearer"}⏎
$ curl --insecure --location --request POST 'https://localhost/_/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=c001d00d-5ecc-beef-ca4e-b00b1e54a111' \
--data-urlencode 'scope=application openid' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
--data-urlencode 'client_assertion=eyJhb [...] jTw'
{"access_token":"wOYtgCLxLXlELORrwZlmeiqqMQ4kRzV-STU2_Sollas.mwlQGCZWXN7G2IoegUe1P0Vw5iGoKrkOzOaplhMSjm4","expires_in":3599,"scope":"application openid","token_type":"bearer"}
Patches
This issue is patched in 0.31.0.
Workarounds
Do not allow clients to use private_key_jwt.
References
https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication
- Record
GHSA-v3q9-2p3m-7g43- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N - Weakness
- CWE-287, CWE-345
- Updated
- 2026-11-02
OSVGO-2021-0110 No score
Token reuse in github.com/ory/fosite
Uniqueness of JWT IDs (jti) are not checked, allowing the JWT to be replayed.
- Record
GO-2021-0110- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
github.com/ory/fositeGo |
before 0.31.0 | 0.31.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| aliases | EUVD | |
| first indexed | CVE List, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2020-15222 is a high vulnerability (CVSS 8.1) in Ory Fosite, published September 24, 2020. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.87%, the 58th percentile. Fixed in github.com/ory/fosite 0.31.0.
References
github.com/ory/fosite/security/advisories/GHSA-v3q9-2p3m-7g43
github.com/ory/fosite/commit/0c9e0f6d654913ad57c507dd9a36631e1858a3e9
openid.net/specs/openid-connect-core-1_0.html
nvd.nist.gov/vuln/detail/CVE-2020-15222
github.com/ory/fosite/releases/tag/v0.31.0
pkg.go.dev/vuln/GO-2021-0110
github.com/advisories/GHSA-v3q9-2p3m-7g43
github.com/ory/fosite