There’s a new vulnerability in the Node.js jsonwebtoken library getting attention. CVE-2022-23529, or GHSA-27h2-hvpr-p74q are the identifiers this vulnerability has been assigned. It’s not just one thing though, there were four fixes to jsonwebtoken version 9.0.0. For now we’re going to focus on CVE-2022-23529 which is getting the most attention due to a high CVSS score. There’s added complexity around the score as NVD scores it a 9.8 (critical), the researcher that found it scored it a 7.6 (high), and the GHSA advisory rates it medium.
Note: How you use the library actually determines your severity, it’s unlikely most users of this library will be vulnerable, the vulnerability only affects unique uses.
The jsonwebtoken library is a Node.js library for working with JSON Web Tokens, or JWT. JWT is used as a way to authenticate web services. This library is downloaded more than 9 million times per week, which is a pretty substantial number. It’s easy to say this is a well used library.
Whenever there’s an issue like what we’re seeing in the jsonwebtoken library, there’s questions about how to actually find and fix it. A lot of articles and advisories will say “just upgrade the package”, but that’s meaningless advice. How do we know if we’re using jsonwebtoken? How do we know if we’re using a vulnerable version? And how do we actually upgrade it? Let’s go over all of these questions, and we will use a Software Bill of Materials (SBOM) as our vehicle for helping
First we have to find jsonwebtoken in our projects and products. We’re going to use Syft and a very simple example for this. We start out in a directory named “jwt”, then we will create a directory called “project”, install jsonwebtoken version 8.5.0 in it, and generate an SBOM with Syft.
➜ jwt$ mkdir project
➜ jwt$ cd project
➜ project$ npm install [email protected]
added 15 packages, and audited 16 packages in 629ms
➜ project$ cd ..
➜ jwt$ syft dir:project -o json > sbom.json
✔ Indexed project
r] Cataloged packages [15 packages]
➜ jwt$
We can see jsonwebtoken version 8.5.0 is installed if we look at the SBOM file
➜ jwt$ cat sbom.json | jq '.artifacts[] | select(.name == "jsonwebtoken")'
{
"id": "94476b6a2fbdc8c5",
"name": "jsonwebtoken",
"version": "8.5.0",
"type": "npm",
"foundBy": "javascript-lock-cataloger",
"locations": [
{
"path": "/path/to/project/package-lock.json"
}
],
"licenses": [],
"language": "javascript",
"cpes": [
"cpe:2.3:a:jsonwebtoken:jsonwebtoken:8.5.0:*:*:*:*:*:*:*",
"cpe:2.3:a:*:jsonwebtoken:8.5.0:*:*:*:*:*:*:*"
],
"purl": "pkg:npm/[email protected]"
}
➜ jwt$
We could create an SBOM for all of our projects and look through them for versions of jswonwebtoken that are older than 9.0.0, but that can be a chore, especially if you have a lot of projects. It’s far easier to rely on a vulnerability scanner such as Grype to scan projects and report back the findings. Here’s what we get if we scan our project with Grype
➜ jwt$ ls
project sbom.json
➜ jwt$ grype sbom:sbom.json
✔ Vulnerability DB [no update available]
✔ Scanned image [4 vulnerabilities]
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY
jsonwebtoken 8.5.0 9.0.0 npm GHSA-27h2-hvpr-p74q High
jsonwebtoken 8.5.0 9.0.0 npm GHSA-8cf7-32gw-wr33 Medium
jsonwebtoken 8.5.0 9.0.0 npm GHSA-hjrf-2m68-5959 Medium
jsonwebtoken 8.5.0 9.0.0 npm GHSA-qwph-4952-7xr6 Medium
➜ jwt$
Remember back when I said there are four vulnerabilities? Now we can see all four with a scan like this. Grype would also report other findings if they existed in our application.
We use Grype to scan the SBOM in our above example. Grype can directly scan a directory, but we’re not using a directory scan. SBOMs scan faster and give us a nice point-in-time snapshot of what packages are installed.
Now that we know we have jsonwebtoken, and we know we have a vulnerable version, how can we upgrade the package? We know we have to move to version 9.0.0 and we have version 8 installed. There have been some breaking changes. You can see those in the changelog document. For the purpose of simplicity we will ignore possible breaking changes.
We can run `npm update` to upgrade our jsonwebtoken package
➜ project$ npm update
changed 1 package, and audited 16 packages in 4s
➜ project$ cd ..
➜ jwt$ syft dir:project -o json > upgraded-sbom.json
✔ Indexed project
✔ Cataloged packages [15 packages]
➜ jwt$ grype sbom:upgraded-sbom.json
✔ Vulnerability DB [no update available]
✔ Scanned image [4 vulnerabilities]
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY
jsonwebtoken 8.5.1 9.0.0 npm GHSA-27h2-hvpr-p74q High
jsonwebtoken 8.5.1 9.0.0 npm GHSA-8cf7-32gw-wr33 Medium
jsonwebtoken 8.5.1 9.0.0 npm GHSA-hjrf-2m68-5959 Medium
jsonwebtoken 8.5.1 9.0.0 npm GHSA-qwph-4952-7xr6 Medium
➜ jwt$
Notice if we just run `npm update` we end up at version 8.5.1 instead of 9. This is because of those breaking changes. You have to run ‘npm install [email protected]` to update to the version we want.
➜ project$ npm install [email protected]
added 3 packages, removed 7 packages, changed 2 packages, and audited 12 packages in 5s
➜ project$ cd ..
➜ jwt$ syft dir:project -o json > 9.0-sbom.json
✔ Indexed project
✔ Cataloged packages [11 packages]
➜ jwt$ grype sbom:9.0-sbom.json
✔ Vulnerability DB [no update available]
✔ Scanned image [0 vulnerabilities]
No vulnerabilities found
➜ jwt$
Our package is updated and no vulnerabilities are found! In the real world it’s rarely this simple. Most modern applications are large and often have library versions that can’t be easily upgraded. For our oversimple example however, this is the output we expect.
This may be a simple contrived example, but the fundamental concept applies to any package and vulnerability. We can use tools like Syft and Grype to know what we have, what vulnerabilities affect our project, then we can verify we upgraded everything correctly. I hope this deep dive into the example scenario provides the groundwork to help you confidently approach the jsonwebtoken vulnerability to keep your organization safe from susceptible libraries.
Josh Bressers
Josh Bressers is vice president of security at Anchore where he guides security feature development for the company’s commercial and open source solutions. He serves on the Open Source Security Foundation technical advisory council and is a co-founder of the Global Security Database project, which is a Cloud Security Alliance working group that is defining the future of security vulnerability identifiers.