CVE-2023-22893
Description
Strapi through 4.5.5 does not verify the access or ID tokens issued during the OAuth flow when the AWS Cognito login provider is used for authentication. A remote attacker could forge an ID token that is signed using the 'None' type algorithm to bypass authentication and impersonate any user that use AWS Cognito for authentication.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Strapi before 4.5.6 fails to validate AWS Cognito ID tokens, enabling attackers to forge tokens with 'None' algorithm and impersonate any user.
Vulnerability
Details
CVE-2023-22893 is an authentication bypass in Strapi (through version 4.5.5) that specifically affects installations using the AWS Cognito login provider. The root cause is the lack of verification of the access or ID tokens issued during the OAuth flow. Strapi accepts tokens signed with the 'None' algorithm, allowing an attacker to forge a valid-looking ID token without a proper signature [1][4].
Exploitation
An unauthenticated remote attacker can craft a malicious JWT using the 'None' algorithm and submit it to Strapi's login endpoint. The server does not validate the token's signature or algorithm, so it accepts the forged token and authenticates the attacker as the user specified in the token claims. No prior access or special privileges are required. The attack only applies when Strapi is configured with the AWS Cognito provider [2].
Impact
Successful exploitation allows the attacker to impersonate any user that uses AWS Cognito for authentication. If the impersonated user has administrative privileges, the attacker gains full control over the Strapi instance, including the ability to modify content, access sensitive data, and potentially execute further attacks (as demonstrated by chaining with other vulnerabilities like CVE-2023-22621) [1].
Mitigation
Strapi patched this vulnerability in version 4.5.6. Users are strongly advised to upgrade immediately. Strapi version 3.x.x has reached end-of-life and will not receive security updates, so users on v3 must migrate to a patched v4.x version. No workarounds are available beyond upgrading [2][4].
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
@strapi/plugin-users-permissionsnpm | >= 3.2.1, < 4.6.0 | 4.6.0 |
Affected products
2- Strapi/Strapidescription
Patches
38bbbd7383a20Split the url to fill origin and path values in purest
1 file changed · +3 −3
packages/plugins/users-permissions/server/services/providers-registry.js+3 −3 modified@@ -17,8 +17,8 @@ const getCognitoPayload = async ({ idToken, jwksUrl, purest }) => { const config = { cognito: { discovery: { - origin: jwksUrl, - path: '', + origin: jwksUrl.origin, + path: jwksUrl.pathname, }, }, }; @@ -62,7 +62,7 @@ const getInitialProviders = ({ purest }) => ({ }); }, async cognito({ query, providers }) { - const jwksUrl = providers.cognito.jwksurl; + const jwksUrl = new URL(providers.cognito.jwksurl); const idToken = query.id_token; const tokenPayload = await getCognitoPayload({ idToken, jwksUrl, purest }); return {
eeab43b57707Store jwk set url in strapi core
2 files changed · +20 −6
packages/plugins/users-permissions/admin/src/pages/Providers/utils/forms.js+15 −0 modified@@ -173,6 +173,21 @@ const forms = { }, }, ], + [ + { + intlLabel: { + id: getTrad({ id: 'PopUpForm.Providers.jwksurl.label' }), + defaultMessage: 'JWKS URL', + }, + name: 'jwksurl', + type: 'text', + placeholder: textPlaceholder, + size: 12, + validations: { + required: false, + }, + }, + ], [ {
packages/plugins/users-permissions/server/services/providers-registry.js+5 −6 modified@@ -4,7 +4,7 @@ const { strict: assert } = require('assert'); const jwt = require('jsonwebtoken'); const jwkToPem = require('jwk-to-pem'); -const getCognitoPayload = async (idToken, purest) => { +const getCognitoPayload = async ({ idToken, jwksUrl, purest }) => { const { header: { kid }, payload, @@ -14,12 +14,10 @@ const getCognitoPayload = async (idToken, purest) => { throw new Error('The provided token is not valid'); } - const { iss } = payload; - const config = { cognito: { discovery: { - origin: `${iss}/.well-known/jwks.json`, + origin: jwksUrl, path: '', }, }, @@ -63,9 +61,10 @@ const getInitialProviders = ({ purest }) => ({ }; }); }, - async cognito({ query }) { + async cognito({ query, providers }) { + const jwksUrl = providers.cognito.jwksurl; const idToken = query.id_token; - const tokenPayload = await getCognitoPayload(idToken, purest); + const tokenPayload = await getCognitoPayload({ idToken, jwksUrl, purest }); return { username: tokenPayload['cognito:username'], email: tokenPayload.email,
46f8f9837833Verify cognito token with AWS
3 files changed · +53 −12
packages/plugins/users-permissions/package.json+1 −0 modified@@ -32,6 +32,7 @@ "bcryptjs": "2.4.3", "grant-koa": "5.4.8", "jsonwebtoken": "^8.1.0", + "jwk-to-pem": "2.0.5", "koa": "^2.13.4", "koa2-ratelimit": "^1.1.2", "lodash": "4.17.21",
packages/plugins/users-permissions/server/services/providers-registry.js+49 −11 modified@@ -2,6 +2,50 @@ const { strict: assert } = require('assert'); const jwt = require('jsonwebtoken'); +const jwkToPem = require('jwk-to-pem'); + +const getCognitoPayload = async (idToken, purest) => { + const { + header: { kid }, + payload, + } = jwt.decode(idToken, { complete: true }); + + if (!payload || !kid) { + throw new Error('The provided token is not valid'); + } + + const { iss } = payload; + + const config = { + cognito: { + discovery: { + origin: `${iss}/.well-known/jwks.json`, + path: '', + }, + }, + }; + try { + const cognito = purest({ provider: 'cognito', config }); + // get the JSON Web Key (JWK) for the user pool + const { body: jwk } = await cognito('discovery').request(); + // Get the key with the same Key ID as the provided token + const key = jwk.keys.find(({ kid: jwkKid }) => jwkKid === kid); + const pem = jwkToPem(key); + + // https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html + const decodedToken = await new Promise((resolve, reject) => { + jwt.verify(idToken, pem, { algorithms: ['RS256'] }, (err, decodedToken) => { + if (err) { + reject(); + } + resolve(decodedToken); + }); + }); + return decodedToken; + } catch (err) { + throw new Error('There was an error verifying the token'); + } +}; const getInitialProviders = ({ purest }) => ({ async discord({ accessToken }) { @@ -20,18 +64,12 @@ const getInitialProviders = ({ purest }) => ({ }); }, async cognito({ query }) { - // get the id_token const idToken = query.id_token; - // decode the jwt token - const tokenPayload = jwt.decode(idToken); - if (!tokenPayload) { - throw new Error('unable to decode jwt token'); - } else { - return { - username: tokenPayload['cognito:username'], - email: tokenPayload.email, - }; - } + const tokenPayload = await getCognitoPayload(idToken, purest); + return { + username: tokenPayload['cognito:username'], + email: tokenPayload.email, + }; }, async facebook({ accessToken }) { const facebook = purest({ provider: 'facebook' });
yarn.lock+3 −1 modified@@ -15118,7 +15118,7 @@ jwa@^2.0.0: ecdsa-sig-formatter "1.0.11" safe-buffer "^5.0.1" -jwk-to-pem@^2.0.5: +jwk-to-pem@2.0.5, jwk-to-pem@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/jwk-to-pem/-/jwk-to-pem-2.0.5.tgz#151310bcfbcf731adc5ad9f379cbc8b395742906" integrity sha512-L90jwellhO8jRKYwbssU9ifaMVqajzj3fpRjDKcsDzrslU9syRbFqfkXtT4B89HYAap+xsxNcxgBSB09ig+a7A== @@ -18081,6 +18081,8 @@ path-case@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/path-case/-/path-case-2.1.1.tgz#94b8037c372d3fe2906e465bb45e25d226e8eea5" integrity sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU= + dependencies: + no-case "^2.2.0" path-dirname@^1.0.0: version "1.0.2"
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
9- github.com/advisories/GHSA-583x-23h9-f5w7ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-22893ghsaADVISORY
- github.com/strapi/strapi/blob/v4.5.6/packages/plugins/users-permissions/server/services/providers-registry.jsghsaWEB
- github.com/strapi/strapi/commit/46f8f98378338f18b5c6139d0157a8f71bf4de83ghsaWEB
- github.com/strapi/strapi/commit/8bbbd7383a20bb7cb163c8b462baffee559e994fghsaWEB
- github.com/strapi/strapi/commit/eeab43b57707d7ef275076d27be6eabc72bd71a7ghsaWEB
- strapi.io/blog/security-disclosure-of-vulnerabilities-cveghsaWEB
- www.ghostccamm.com/blog/multi_strapi_vulnsghsaWEB
- www.ghostccamm.com/blog/multi_strapi_vulns/mitre
News mentions
0No linked articles in our index yet.