From 7f3426fbe815496e4b9dbd1b7b78aeb49c47bad2 Mon Sep 17 00:00:00 2001 From: Sebastien Larinier Date: Fri, 15 May 2026 12:01:06 +0200 Subject: [PATCH] ci: audit dependencies on every PR + bump happy-dom past RCE CVE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an `npm audit --audit-level=high` step after the test run. It fails the build if any package in our graph has a known high or critical vulnerability (GitHub Advisory). Cheap, generic supply-chain guardrail — no list to maintain on our side. Running the audit immediately exposed a critical CVE in our existing happy-dom range (^15.11.7 — VM Context Escape leading to RCE, GHSA-37j7-fg3j-429f). Bumped to ^20.9.0 which carries the fix. Local `npm run ci` is green on 96/96 tests with the new happy-dom; the API surface we use (createElement, KeyboardEvent, document.title, document.head.innerHTML) is unchanged across the major. Six moderate vulnerabilities remain in the vite/vitest chain — those sit below the high threshold and don't fail the audit. We can revisit if they get re-classified. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 9 ++++ package-lock.json | 91 ++++++++++++++++++++++++++++++---------- package.json | 2 +- 3 files changed, 80 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 64a63c6..4f29c16 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,15 @@ jobs: - name: Test run: npm test + # Sécurité supply chain : fail si une vulnérabilité de niveau `high` + # ou `critical` est connue dans le graphe de dépendances. La base + # CVE GitHub Advisory est consultée à chaque run, on n'a rien à + # maintenir côté repo. --omit=dev pourrait filtrer les vulnérabilités + # qui ne touchent que le tooling de tests, mais ici l'arbre est + # 100% devDependencies — on audit tout. + - name: Audit dependencies + run: npm audit --audit-level=high + # Bonus: validate manifest.json is parseable and the extension can # be packaged (catches mistakes that would only show up at install time). - name: Validate manifest diff --git a/package-lock.json b/package-lock.json index 621932b..ea938ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "@vitest/coverage-v8": "^2.1.8", "eslint": "^9.17.0", "globals": "^15.14.0", - "happy-dom": "^15.11.7", + "happy-dom": "^20.9.0", "vitest": "^2.1.8" }, "engines": { @@ -1145,6 +1145,33 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/node": { + "version": "25.8.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.8.0.tgz", + "integrity": "sha512-TCFSk8IZh+iLX1xtksoBVtdmgL+1IX0fC9BeU4QqFSuNdN/K+HUlhqOzEmSYYpZUVsLYcPqc9KX+60iDuninSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": ">=7.24.0 <7.24.7" + } + }, + "node_modules/@types/whatwg-mimetype": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz", + "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@vitest/coverage-v8": { "version": "2.1.9", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.9.tgz", @@ -1551,9 +1578,9 @@ "license": "MIT" }, "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -1975,18 +2002,21 @@ } }, "node_modules/happy-dom": { - "version": "15.11.7", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-15.11.7.tgz", - "integrity": "sha512-KyrFvnl+J9US63TEzwoiJOQzZBJY7KgBushJA8X61DMbNsH+2ONkDuLDnCnwUiPTF42tLoEmrPyoqbenVA5zrg==", + "version": "20.9.0", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.9.0.tgz", + "integrity": "sha512-GZZ9mKe8r646NUAf/zemnGbjYh4Bt8/MqASJY+pSm5ZDtc3YQox+4gsLI7yi1hba6o+eCsGxpHn5+iEVn31/FQ==", "dev": true, "license": "MIT", "dependencies": { - "entities": "^4.5.0", - "webidl-conversions": "^7.0.0", - "whatwg-mimetype": "^3.0.0" + "@types/node": ">=20.0.0", + "@types/whatwg-mimetype": "^3.0.2", + "@types/ws": "^8.18.1", + "entities": "^7.0.1", + "whatwg-mimetype": "^3.0.0", + "ws": "^8.18.3" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/has-flag": { @@ -2905,6 +2935,13 @@ "node": ">= 0.8.0" } }, + "node_modules/undici-types": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "dev": true, + "license": "MIT" + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3064,16 +3101,6 @@ } } }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, "node_modules/whatwg-mimetype": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", @@ -3222,6 +3249,28 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/ws": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", + "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 6b63684..77447fb 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@vitest/coverage-v8": "^2.1.8", "eslint": "^9.17.0", "globals": "^15.14.0", - "happy-dom": "^15.11.7", + "happy-dom": "^20.9.0", "vitest": "^2.1.8" }, "engines": {