From 37bf894412b4da0f0507dd8f1384e6f101ce14b2 Mon Sep 17 00:00:00 2001 From: Paul Nothaft Date: Thu, 7 May 2026 13:51:55 +0200 Subject: [PATCH] fix(security): patch 18 dependency CVEs (axios + transitives + nodemailer + i18next-http-backend) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the open Trivy code-scanning alerts for app-side dependencies. The npm-bundled CVEs in /usr/local/lib/node_modules/npm (picomatch, brace-expansion, ip-address inside the Node image itself) are deferred to a separate Node-base-image PR — they're build-environment-side and need their own compatibility testing. | Package | From | To | CVEs cleared | |---|---|---|---| | axios (backend + frontend) | 1.14.0 | 1.15.2 | CVE-2026-42264 (HIGH), CVE-2026-42043 (HIGH), CVE-2026-42035 (HIGH), CVE-2026-42033 (HIGH), CVE-2026-42044, CVE-2026-42042, CVE-2026-42041, CVE-2026-42040, CVE-2026-42039, CVE-2026-42038, CVE-2026-42037, CVE-2026-42036, CVE-2026-42034, CVE-2026-40175, CVE-2025-62718 | | nodemailer (backend) | ^7.0.13 | ^8.0.5 | GHSA-vvjj-xcjg-gr5g, GHSA-c7w3-x93f-qmm8 | | i18next-http-backend (frontend) | ^3.0.2 | ^3.0.5 | CVE-2026-41691 | | uuid (backend) | ^11.1.0 | ^11.1.1 | CVE-2026-41907 | | postcss (frontend, devDep) | ^8.4.21 | ^8.5.10 | CVE-2026-41305 | For transitives whose direct parents haven't released a version that picks up the patched range, pinned via npm overrides: | Package | Min | CVE | |---|---|---| | follow-redirects (backend + frontend) | >=1.16.0 | GHSA-r4q5-vmmm-2653 | | fast-xml-parser (backend) | >=5.7.0 | CVE-2026-41650 | | @tootallnate/once (backend) | >=3.0.1 | CVE-2026-3449 | | ip-address (backend) | >=10.1.1 | CVE-2026-42338 | PR #268 originally pinned axios to 1.14.0 to avoid a supply-chain attack on a specific compromised version range. The 1.15.x series are post-incident upstream releases — clean. Confirmed with the maintainer before bumping. * `npx tsc --noEmit` (frontend) — clean * `npx vite build` (frontend) — clean (~4s, existing bundle-size warning, not new) * Backend module-load smoke test — all critical modules load (`auth`, `adminAuth` middleware, `emailProcessor`, `recaptcha`, `storage`) with the new axios + nodemailer * Lockfile re-verification — every targeted CVE now resolves to the patched version range * npm-bundled CVEs inside `/usr/local/lib/node_modules/npm/` — picomatch CVE-2026-33671 (HIGH), CVE-2026-33672, brace-expansion CVE-2026-33750, ip-address (npm-internal) CVE-2026-42338. These live in the Node base image and require a Node base image bump with its own compatibility testing — separate PR. Targeting `beta` so the bumps go through the normal release-please flow before promotion to `main`. --- backend/package-lock.json | 85 ++++++++++++++++++++++---------------- backend/package.json | 13 +++--- frontend/package-lock.json | 44 ++++++++++---------- frontend/package.json | 9 ++-- 4 files changed, 84 insertions(+), 67 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index 8b15dc83..852786e6 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1,19 +1,19 @@ { "name": "picpeak-backend", - "version": "3.42.1", + "version": "3.43.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "picpeak-backend", - "version": "3.42.1", + "version": "3.43.0", "dependencies": { "@aws-sdk/client-s3": "^3.850.0", "@aws-sdk/lib-storage": "^3.850.0", "@aws-sdk/s3-request-presigner": "^3.850.0", "adm-zip": "^0.5.16", "archiver": "^5.3.1", - "axios": "1.14.0", + "axios": "1.15.2", "bcrypt": "6.0.0", "chokidar": "4.0.3", "cookie-parser": "^1.4.7", @@ -38,7 +38,7 @@ "mime-types": "^3.0.1", "multer": "^2.0.2", "node-cron": "^3.0.2", - "nodemailer": "^7.0.13", + "nodemailer": "^8.0.5", "pg": "^8.16.3", "react-i18next": "^15.6.0", "sanitize-html": "^2.17.0", @@ -46,7 +46,7 @@ "sqlite3": "^5.1.6", "swagger-jsdoc": "^6.2.8", "swagger-ui-express": "^5.0.1", - "uuid": "^11.1.0", + "uuid": "^11.1.1", "winston": "^3.8.2", "zxcvbn": "^4.4.2" }, @@ -2594,6 +2594,18 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@nodable/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3538,13 +3550,13 @@ } }, "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-3.0.1.tgz", + "integrity": "sha512-VyMVKRrpHTT8PnotUeV8L/mDaMwD5DaAKCFLP73zAqAtvF0FCqky+Ki7BYbFCYQmqFyTe9316Ed5zS70QUR9eg==", "license": "MIT", "optional": true, "engines": { - "node": ">= 6" + "node": ">= 10" } }, "node_modules/@types/babel__core": { @@ -4009,9 +4021,9 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz", - "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", + "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", @@ -5781,9 +5793,9 @@ "license": "MIT" }, "node_modules/fast-xml-builder": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", - "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.9.tgz", + "integrity": "sha512-jcyKVSEX13iseJqg7n/KWw+xnu/7fdrZ333Fac54KjHDIELVCfDDJXYIm6DTJ0Su4gSzrhqiK0DzY/wZbF40mw==", "funding": [ { "type": "github", @@ -5796,9 +5808,9 @@ } }, "node_modules/fast-xml-parser": { - "version": "5.5.10", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.10.tgz", - "integrity": "sha512-go2J2xODMc32hT+4Xr/bBGXMaIoiCwrwp2mMtAvKyvEFW6S/v5Gn2pBmE4nvbwNjGhpcAiOwEv7R6/GZ6XRa9w==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.3.tgz", + "integrity": "sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==", "funding": [ { "type": "github", @@ -5807,9 +5819,10 @@ ], "license": "MIT", "dependencies": { - "fast-xml-builder": "^1.1.4", - "path-expression-matcher": "^1.2.1", - "strnum": "^2.2.2" + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.7", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" @@ -5983,9 +5996,9 @@ "license": "MIT" }, "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", @@ -6753,9 +6766,9 @@ } }, "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", "license": "MIT", "optional": true, "engines": { @@ -8746,9 +8759,9 @@ "license": "MIT" }, "node_modules/nodemailer": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.13.tgz", - "integrity": "sha512-PNDFSJdP+KFgdsG3ZzMXCgquO7I6McjY2vlqILjtJd0hy8wEvtugS9xKRF2NWlPNGxvLCXlTNIae4serI7dinw==", + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.7.tgz", + "integrity": "sha512-pkjE4mkBzQjdJT4/UmlKl3pX0rC9fZmjh7c6C9o7lv66Ac6w9WCnzPzhbPNxwZAzlF4mdq4CSWB5+FbK6FWCow==", "license": "MIT-0", "engines": { "node": ">=6.0.0" @@ -9139,9 +9152,9 @@ } }, "node_modules/path-expression-matcher": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.4.0.tgz", - "integrity": "sha512-s4DQMxIdhj3jLFWd9LxHOplj4p9yQ4ffMGowFf3cpEgrrJjEhN0V5nxw4Ye1EViAGDoL4/1AeO6qHpqYPOzE4Q==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", "funding": [ { "type": "github", @@ -11216,9 +11229,9 @@ } }, "node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz", + "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" diff --git a/backend/package.json b/backend/package.json index be52caf2..c6d13ce5 100644 --- a/backend/package.json +++ b/backend/package.json @@ -19,7 +19,7 @@ "@aws-sdk/s3-request-presigner": "^3.850.0", "adm-zip": "^0.5.16", "archiver": "^5.3.1", - "axios": "1.14.0", + "axios": "1.15.2", "bcrypt": "6.0.0", "chokidar": "4.0.3", "cookie-parser": "^1.4.7", @@ -44,7 +44,7 @@ "mime-types": "^3.0.1", "multer": "^2.0.2", "node-cron": "^3.0.2", - "nodemailer": "^7.0.13", + "nodemailer": "^8.0.5", "pg": "^8.16.3", "react-i18next": "^15.6.0", "sanitize-html": "^2.17.0", @@ -52,7 +52,7 @@ "sqlite3": "^5.1.6", "swagger-jsdoc": "^6.2.8", "swagger-ui-express": "^5.0.1", - "uuid": "^11.1.0", + "uuid": "^11.1.1", "winston": "^3.8.2", "zxcvbn": "^4.4.2" }, @@ -69,12 +69,15 @@ }, "glob": "^11.1.0", "js-yaml": "^4.1.1", - "fast-xml-parser": ">=5.5.10", + "fast-xml-parser": ">=5.7.0", "qs": ">=6.14.2", "tar": ">=7.5.13", "brace-expansion": ">=5.0.5", "minimatch": ">=9.0.7", "path-to-regexp": "0.1.13", - "lodash": ">=4.18.1" + "lodash": ">=4.18.1", + "follow-redirects": ">=1.16.0", + "@tootallnate/once": ">=3.0.1", + "ip-address": ">=10.1.1" } } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 89f503d3..a770f42b 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "picpeak-frontend", - "version": "3.42.1", + "version": "3.43.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "picpeak-frontend", - "version": "3.42.1", + "version": "3.43.0", "dependencies": { "@tanstack/react-query": "^5.0.0", "@tiptap/extension-character-count": "^2.26.1", @@ -20,14 +20,14 @@ "@types/dompurify": "^3.0.5", "@types/lodash": "^4.17.20", "@types/react-google-recaptcha": "^2.1.9", - "axios": "1.14.0", + "axios": "1.15.2", "clsx": "^2.0.0", "date-fns": "4.1.0", "dompurify": "^3.2.6", "framer-motion": "^12.33.0", "i18next": "^25.3.1", "i18next-browser-languagedetector": "^8.2.0", - "i18next-http-backend": "^3.0.2", + "i18next-http-backend": "^3.0.5", "justified-layout": "^4.1.0", "linkifyjs": "^4.3.2", "lodash": "^4.17.21", @@ -63,7 +63,7 @@ "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.2.0", "jsdom": "^25.0.1", - "postcss": "^8.4.21", + "postcss": "^8.5.10", "tailwindcss": "^3.3.0", "typescript": "~5.8.3", "typescript-eslint": "^8.34.1", @@ -3020,9 +3020,9 @@ } }, "node_modules/axios": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz", - "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", + "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", @@ -3355,12 +3355,12 @@ } }, "node_modules/cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz", + "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==", "license": "MIT", "dependencies": { - "node-fetch": "^2.6.12" + "node-fetch": "^2.7.0" } }, "node_modules/cross-spawn": { @@ -4080,9 +4080,9 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", @@ -4440,12 +4440,12 @@ } }, "node_modules/i18next-http-backend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-3.0.2.tgz", - "integrity": "sha512-PdlvPnvIp4E1sYi46Ik4tBYh/v/NbYfFFgTjkwFl0is8A18s7/bx9aXqsrOax9WUbeNS6mD2oix7Z0yGGf6m5g==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-3.0.6.tgz", + "integrity": "sha512-mBOqy8993jtqAoj6XaI1XeC/8/9v6EPS+681ziegrPvTB0DoaCY7PpTS0SpY56qLMoS4OI1TZEM2Zf59zNh05w==", "license": "MIT", "dependencies": { - "cross-fetch": "4.0.0" + "cross-fetch": "4.1.0" } }, "node_modules/iconv-lite": { @@ -5333,9 +5333,9 @@ } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", "dev": true, "funding": [ { diff --git a/frontend/package.json b/frontend/package.json index 9db351a6..edc397e2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -24,14 +24,14 @@ "@types/dompurify": "^3.0.5", "@types/lodash": "^4.17.20", "@types/react-google-recaptcha": "^2.1.9", - "axios": "1.14.0", + "axios": "1.15.2", "clsx": "^2.0.0", "date-fns": "4.1.0", "dompurify": "^3.2.6", "framer-motion": "^12.33.0", "i18next": "^25.3.1", "i18next-browser-languagedetector": "^8.2.0", - "i18next-http-backend": "^3.0.2", + "i18next-http-backend": "^3.0.5", "justified-layout": "^4.1.0", "linkifyjs": "^4.3.2", "lodash": "^4.17.21", @@ -67,7 +67,7 @@ "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.2.0", "jsdom": "^25.0.1", - "postcss": "^8.4.21", + "postcss": "^8.5.10", "tailwindcss": "^3.3.0", "typescript": "~5.8.3", "typescript-eslint": "^8.34.1", @@ -79,6 +79,7 @@ }, "overrides": { "glob": "^11.1.0", - "js-yaml": "^4.1.1" + "js-yaml": "^4.1.1", + "follow-redirects": ">=1.16.0" } }