Patching a MEAN Stack: Node.js, Express and Angular SSR Security Releases in 2026
The main 2026 security releases for Node.js, Express middleware and Angular SSR in one place, with affected and fixed versions. Plus how to check what you actually run, a patch routine for a production app with staging and rollback, and what to monitor afterwards.

If you run a MEAN stack in production on 5 November 2026, these are the minimum versions. Node.js: 26.12.1, 24.22.1 or 22.23.4. The 21 October release fixed CVE-2026-111497, a Brotli decoder bug that allows remote code execution. Express middleware: proxy-addr 2.0.8, body-parser 2.4.0 (or 1.20.9 on Express 4), compression 1.8.2 and multer 2.5.0. Angular SSR: framework packages on 22.2.1 or later, @angular/ssr on 22.1.7 or later and @angular/build on 22.2.5 or later. Node.js has also scheduled another security release for 26.x, 24.x and 22.x, on or shortly after 11 November 2026, with the highest severity rated High. Below you will find the advisories that matter most in one place, how to check what you actually run, and a patch routine that keeps rollback easy.
The 2026 advisories, component by component
These tables are a selection, and every row was confirmed on the projects' official pages. The Node.js table covers the five security releases of 2026 so far. The Express table covers July to October 2026; the earlier Express posts (February to June) cover multer, path-to-regexp, multiparty and morgan, so read them too if you are far behind. The Angular table covers the SSR, router, HttpClient and build packages. Node.js posts list the patched release for each line, not per CVE, so "Fixed in" there means the security release for each line. Later releases on the same line include the fixes.
Node.js runtime
| Component | Advisory | Severity | Affected | Fixed in | Source |
|---|---|---|---|---|---|
| Node.js | October release: CVE-2026-111497 (Brotli RCE), CVE-2026-105482, CVE-2026-105483, CVE-2026-106069, plus 3 Medium and 3 Low | High | 26.x, 24.x, 22.x | 26.12.1, 24.22.1, 22.23.4 | nodejs.org, 21 Oct |
| Node.js | July release: CVE-2026-56846, CVE-2026-56848 (HTTP/2), CVE-2026-58043 (Permission Model), plus 5 Medium and 3 Low | High | 26.x, 24.x, 22.x | 26.5.1, 24.18.1, 22.23.2 | nodejs.org, 29 Jul |
| Node.js | June release: CVE-2026-48933 (WebCrypto AES crash), CVE-2026-48618 (TLS wildcard bypass), plus 6 Medium and 4 Low | High | 26.x, 24.x, 22.x | 26.3.1, 24.17.0, 22.23.0 | nodejs.org, 18 Jun |
| Node.js | March release: CVE-2026-21710 (__proto__ header crash), incomplete fix for CVE-2026-21637, plus 5 Medium and 2 Low | High | 25.x, 24.x, 22.x, 20.x | 25.8.2, 24.14.1, 22.22.2, 20.20.2 | nodejs.org, 24 Mar |
| Node.js | January release: CVE-2025-55131, CVE-2025-55130, CVE-2025-59465 | High | 25.x, 24.x, 22.x, 20.x | 25.3.0, 24.13.0, 22.22.0, 20.20.0 | nodejs.org, 13 Jan |
Node 20 reached end of life on 30 April 2026, and Node 25 is end of life too. The Node.js security posts state that end-of-life versions are affected by security releases, so "we are on 20" means "we are unpatched". Which line to move to is covered in Node.js LTS versions for production.
Express and its middleware
| Component | Advisory | Severity | Affected | Fixed in | Source |
|---|---|---|---|---|---|
proxy-addr (trust proxy) | CVE-2026-90711: an IPv4-mapped IPv6 subnet matched every address, so req.ip could be spoofed | Critical | 1.1.0 to before 2.0.8 | 2.0.8 | expressjs.com, 30 Sep |
| body-parser | CVE-2026-111181 (GHSA-27r3-jxmh-p828): trailing bytes after a gzip body crash the process | High | 2.0.0 to before 2.4.0; before 1.20.9 | 2.4.0, 1.20.9 | expressjs.com, 31 Oct |
| body-parser | CVE-2026-12590: an invalid limit silently disabled the size check | Low | 2.0.0 to before 2.3.0; before 1.20.6 | 2.3.0, 1.20.6 | expressjs.com, 31 Jul |
| compression | CVE-2026-87776: zlib stream not destroyed on abort, native memory leak | High | before 1.8.2 | 1.8.2 | expressjs.com, 30 Sep |
| multer | CVE-2026-113872 (GHSA-q7qp-rjg7-q26m): crash when a request is torn down while an async fileFilter is pending | High | 2.0.0 to before 2.5.0 | 2.5.0 | expressjs.com, 31 Oct |
| multer | CVE-2026-77037, CVE-2026-77078, CVE-2026-82333 (High), CVE-2026-77063 (Low) | High | before 2.3.0 (CVE-2026-77037: 2.2.0 only) | 2.3.0 | expressjs.com, 31 Aug |
| multer | CVE-2026-88932: aborted uploads left orphaned files | Medium | 2.2.0 to before 2.4.0 | 2.4.0 | expressjs.com, 30 Sep |
| morgan | CVE-2026-87859 (log injection); CVE-2026-15603 (log forging) | Medium | before 1.12.1; before 1.12.0 | 1.12.1 | expressjs.com, 30 Sep / 31 Aug |
| cookies | CVE-2026-88038: domain/path written unescaped into Set-Cookie | Medium | before 0.9.2 | 0.9.2 | expressjs.com, 30 Sep |
Express 5.3.0, released in October, raised its own minimums: qs (for CVE-2026-2391, CVE-2026-82417 and CVE-2026-82562), proxy-addr ^2.0.8 and body-parser ^2.3.0. Its caret range lets npm update pull in body-parser 2.4.0. If you use hbs or multiparty, the same Express posts cover fixes in hbs 4.3.1 and multiparty 4.3.1.
Angular SSR, router, HttpClient and @angular/build
| Component | Advisory | Severity | Affected | Fixed in | Source |
|---|---|---|---|---|---|
| @angular/ssr | CVE-2026-27739 (GHSA-x288-3778-4hhx): SSRF and header injection via Host/X-Forwarded-* | Critical (9.2) | 21.x before 21.1.5; 20.x before 20.3.17; 19.x before 19.2.21 | 21.1.5 (21.2.0-rc.1), 20.3.17, 19.2.21 | angular-cli, 23 Feb |
| @angular/ssr | CVE-2026-27738, CVE-2026-33397, CVE-2026-44437: open redirects (X-Forwarded-Prefix and protocol-relative URL handling) | Moderate | see each advisory | 21.2.9, 20.3.25 cover all three | angular-cli, 23 Feb / 19 Mar / 30 Apr |
| @angular/ssr | CVE-2026-104871 (GHSA-7g7c-h8rr-7p6q): path traversal in CommonEngine on Windows | Moderate | 22.x before 22.1.7; 21.x before 21.2.23; 20.x before 20.3.36 | 22.1.7, 21.2.23, 20.3.36 | angular-cli, 2 Sep |
| @angular/platform-server | CVE-2026-88056 (SSRF, credential disclosure) and CVE-2026-88058 (SSR XSS) | High | 22.x before 22.1.4; 21.x before 21.2.22; 20.x before 20.3.30 | 22.1.4, 21.2.22, 20.3.30 | angular, 27 Aug |
| @angular/platform-server | CVE-2026-101895 (GHSA-f67j-2jqw-jpq7): infinite loop on a malformed DOCTYPE | High | 22.x before 22.1.6; 21.x before 21.2.23; 20.x before 20.3.31 | 22.1.6, 21.2.23, 20.3.31 | angular, 9 Sep |
| @angular/platform-server | CVE-2026-111754 (GHSA-w739-gvwx-grc3): open redirect via protocol-relative URLs | Moderate | 22.x before 22.2.1; 21.x before 21.2.25; 20.x before 20.3.33 | 22.2.1, 21.2.25, 20.3.33 | angular, 30 Sep |
| @angular/router | CVE-2026-101896 (numeric matrix params), CVE-2026-111752 (empty-path outlets), CVE-2026-111751 (RouterLink query params): SSR denial of service | High | 22.x before 22.2.1; 21.x before 21.2.25; 20.x before 20.3.33 (CVE-2026-111751: 22.x and 21.2.x only) | 22.2.1, 21.2.25, 20.3.33 | angular, 23 Sep to 1 Oct |
| @angular/common | CVE-2026-88059 (GHSA-p297-fm68-3q8c): transfer cache stores authenticated responses with withRequestsMadeViaParent | Moderate | 22.x before 22.1.1; 21.x before 21.2.20; 20.x before 20.3.28 | 22.1.1, 21.2.20, 20.3.28 | angular, 20 Aug |
| @angular/common | CVE-2026-111753 (GHSA-jfgx-762w-99vr): XSRF token leak to cross-origin hosts | High | 21.0.x before 21.0.3; 20.x before 20.3.34 (22.x not affected) | 21.0.3, 20.3.34 | angular, 16 Oct |
| @angular/build | GHSA-w34w-96hf-98hj (no CVE): code injection in generated server manifests; GHSA-jp2q-rh7r-4vjf (Low): XSS in prerendered redirect pages | High (7.7) | 22.x before 22.2.5; 21.x before 21.2.29; 20.x before 20.3.42 | 22.2.5, 21.2.29, 20.3.42 | angular-cli, 28 Oct |
I left out the template-sanitisation (XSS), transfer-cache and service-worker advisories of May to August; every one of them is fixed in 22.1.4 or earlier, so framework packages on 22.2.1 are covered. Version 19 is out of support, and the advisories from late July onwards list no fix for it. Angular 20's LTS also ends on 28 November 2026, so a v20 app has only a few weeks of patches left. The upgrade itself is covered in Upgrading to Angular 22.
Check what you actually run
package.json shows ranges, not versions. The lockfile and the running process are what count. These commands answer "am I affected?" for every row above:
# The runtime that actually serves traffic
node -v
# Every installed copy of the Express middleware, including nested ones
npm ls proxy-addr body-parser compression multer morgan cookies
# Angular framework and tooling (core and CLI packages have different patch numbers)
npm ls @angular/core @angular/platform-server @angular/router @angular/common @angular/ssr @angular/build
# Known advisories for production dependencies, then for everything
npm audit --omit=dev
npm audit
Run both audits. --omit=dev is useful for API dependencies, but @angular/build is a devDependency, and the code it generates runs in your production SSR server. A production-only audit will not report it.
If you deploy containers, ask the image rather than the Dockerfile in your repo, because the tag that is running may not be the one you last committed:
# Node version inside the image that is running
docker run --rm my-api:current node -v
# The base image line, and the digest you can pin for rollback
grep -n "^FROM" Dockerfile
docker image inspect node:24.22.2-alpine --format "{{index .RepoDigests 0}}"
For an Angular SSR app, check both images, because the API and the SSR server often run on different Node versions.
A patch routine for a production app
1. Triage, then patch everything anyway
Read each advisory's conditions, because they tell you how urgent it is. The body-parser and multer bugs crash the process with one unauthenticated request. The proxy-addr bug only matters if your trust proxy value uses IPv4-mapped IPv6 notation. The @angular/build issue needs prerendering with server output. The conditions set the order you patch in, not whether you patch: an advisory that does not apply today can apply after next month's refactor.
2. One layer per deploy
I patch in three separate deploys, so a regression points to one cause:
- Node runtime. Bump the base image to an exact patch tag. This touches TLS, HTTP and zlib for everything in the process.
- Express middleware. A lockfile-only change, using the command from the Express security posts.
- Angular packages. Update within your major, rebuild, and deploy the new SSR bundle.
# Pin the exact patch release, not just "node:24"
FROM node:24.22.2-alpine
# Express middleware: stays inside your semver ranges, updates package-lock.json
npm update proxy-addr body-parser compression multer morgan cookies
# Angular: latest patch of your current major
ng update @angular/cli@^22 @angular/core@^22
If a nested copy will not move because its parent pins an old range, an npm overrides entry forces it. Remove the override once the parent has been updated:
{
"overrides": {
"proxy-addr": "^2.0.8"
}
}
3. Staging with the same artefact
Deploy the exact image you will ship to production, then test the paths these advisories touch:
- a gzip-compressed JSON
POSTto a route that usesexpress.json() - a file upload, and an upload cancelled halfway
req.ipin the logs behind your real proxy- a server-rendered page (200), an unknown URL (404) and a redirect
echo '{"name":"patch test"}' | gzip | curl -s -o /dev/null -w "%{http_code}\n" \
-X POST https://staging.example.com/api/contact \
-H "Content-Type: application/json" -H "Content-Encoding: gzip" --data-binary @-
4. Rollback is a tag, not a rebuild
Keep the previous image tag (or digest) deployable, and keep each layer's change in its own commit. A runtime regression is rolled back by redeploying the old image. A dependency regression is rolled back by reverting the lockfile commit and running npm ci. You should never have to choose between an old Node.js and a new body-parser.
Stopgaps when you cannot patch today
These come from the official advisories and only buy time:
- Brotli RCE (Node.js): upgrading Node.js is the real fix. If you cannot upgrade yet, the Express team suggests rejecting request bodies whose
Content-Encodingis not identity, gzip or deflate. Do it before any body parser runs, and only if you do not need Brotli request bodies. - body-parser gzip crash:
express.json({ inflate: false })rejects compressed bodies instead of crashing. - Angular SSR host headers: set
security.allowedHostsinangular.json(orNG_ALLOWED_HOSTS), and only trustX-Forwarded-*headers behind a proxy you control. - @angular/build manifests: only allow letters, digits, hyphens and underscores in values returned from
getPrerenderParams().
// From the Express October 2026 post: register before every body parser.
app.use((req, res, next) => {
const encoding = (req.get('Content-Encoding') || 'identity').trim().toLowerCase();
if (!['identity', 'gzip', 'deflate'].includes(encoding)) {
return res.status(415).send('Use gzip, deflate, or an uncompressed request body.');
}
next();
});
app.use(express.json());
The 415 status tells clients the encoding is the problem. The HTTP status codes reference covers it and the 400 that Angular returns for an unknown host.
The Node.js release scheduled for 11 November 2026
On 3 November the Node.js project posted a pre-announcement: new 26.x, 24.x and 22.x releases are scheduled for "on or shortly after" Wednesday, 11 November 2026. The highest severity issue fixed is rated High. No CVE details are public yet; they come with the release. Plan the runtime deploy for that week now, and test it like the routine above. Then update this post's minimum versions in your own runbook.
What to monitor
- Announcements: the nodejs-sec group and the Node.js vulnerability blog; the Express blog's security posts; and the security advisory pages of
angular/angularandangular/angular-cli. - Dependencies:
npm auditin CI on every pull request, including dev dependencies, plus Dependabot or a similar tool. Supply-chain risk is a separate problem from known CVEs; see protecting a Node project from npm supply-chain attacks. - Runtime signals: most advisories this year are denial-of-service bugs, so alert on process restarts and crash loops, memory growth, event-loop lag and 5xx rates. After you enable
allowedHosts, watch for a jump in 400 responses. Watch for 302 redirects to external hosts from your SSR server too.
A small, regular routine beats a heroic catch-up. If you want a second pair of hands on a Node.js and Express API, see my Node.js and Express API development service.
Sources
- Node.js: November 2026 security releases (pre-announcement)
- Node.js: October 2026 security releases
- Node.js: July 2026 security releases
- Node.js: June 2026 security releases
- Node.js: March 2026 security releases
- Node.js: January 13, 2026 security releases
- Node.js releases, release schedule and security reporting
- Express: October 2026 security releases and CVE-2026-111181 in body-parser
- Express: September 2026, August 2026 and July 2026 security releases
- Express releases (5.3.0) and Express version support
- angular/angular security advisories
- angular/angular-cli security advisories
- Angular: Versioning and releases and Angular: Security
- Docker official Node.js images




