From 4292d34417e672bcf1c58d0bc15fea5050868e0d Mon Sep 17 00:00:00 2001 From: shrijayan <81805145+shrijayan@users.noreply.github.com> Date: Wed, 24 Jun 2026 18:01:08 +0530 Subject: [PATCH] security: pin GitHub Actions to SHAs and force-upgrade vulnerable transitive deps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Pin all GitHub Actions to immutable commit SHAs to prevent supply-chain attacks via mutable version tags (actions/checkout, pnpm/action-setup, actions/setup-node, codecov/codecov-action, upload-pages-artifact, deploy-pages) — fixes code-scanning alerts #81-#84 - Add pnpm.overrides to force patched versions of transitive dependencies: handlebars@>=4.7.9 (JS injection via AST), js-yaml@>=4.2.0 (DoS via merge key aliases), undici@>=7.28.0 (TLS bypass, header injection, cache poisoning) — fixes Dependabot alerts #18-#27, #43-#53 Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/ci.yml | 8 +- .github/workflows/deploy-landing.yml | 10 +- .github/workflows/release.yml | 6 +- package.json | 7 ++ pnpm-lock.yaml | 135 +++++++++++++++------------ 5 files changed, 94 insertions(+), 72 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92721e1..2e63e47 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,15 +17,15 @@ jobs: node-version: [20, 22] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Install native build tools (Linux) if: runner.os == 'Linux' run: sudo apt-get update && sudo apt-get install -y build-essential python3 - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6 - - uses: actions/setup-node@v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' @@ -38,7 +38,7 @@ jobs: - name: Upload coverage to Codecov if: runner.os == 'Linux' && matrix.node-version == 22 - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 with: token: ${{ secrets.CODECOV_TOKEN }} flags: unittests diff --git a/.github/workflows/deploy-landing.yml b/.github/workflows/deploy-landing.yml index 80dd3d0..9eede27 100644 --- a/.github/workflows/deploy-landing.yml +++ b/.github/workflows/deploy-landing.yml @@ -21,11 +21,11 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6 - - uses: actions/setup-node@v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: ".nvmrc" cache: "pnpm" @@ -42,7 +42,7 @@ jobs: run: cp -r packages/docs/.vitepress/dist packages/landing/dist/docs - name: Upload artifact - uses: actions/upload-pages-artifact@v5 + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5 with: path: packages/landing/dist @@ -55,4 +55,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v5 + uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c47c399..bda8af0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: pull-requests: write steps: - name: Checkout repository - uses: actions/checkout@v7 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: token: ${{ secrets.RELEASE_TOKEN }} fetch-depth: 0 @@ -26,9 +26,9 @@ jobs: - name: Install native build tools run: sudo apt-get update && sudo apt-get install -y build-essential python3 - - uses: pnpm/action-setup@v6 + - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6 - - uses: actions/setup-node@v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version-file: '.nvmrc' cache: 'pnpm' diff --git a/package.json b/package.json index 544c7c5..fd01bd0 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,13 @@ "lint-staged": { "*.ts": "eslint --no-warn-ignored" }, + "pnpm": { + "overrides": { + "handlebars": ">=4.7.9", + "js-yaml": ">=4.2.0", + "undici": ">=7.28.0" + } + }, "packageManager": "pnpm@10.30.3", "engines": { "node": ">=20.0.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a8b55dd..7d7a22e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,11 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + handlebars: '>=4.7.9' + js-yaml: '>=4.2.0' + undici: '>=7.28.0' + importers: .: @@ -77,7 +82,7 @@ importers: version: 6.0.3 vitest: specifier: ^4.1.2 - version: 4.1.2(@types/node@25.5.2)(jsdom@29.1.1)(vite@8.1.0(@types/node@25.5.2)(esbuild@0.27.3)(yaml@2.9.0)) + version: 4.1.2(@types/node@25.5.2)(jsdom@29.1.1)(vite@8.1.0(@types/node@25.5.2)(esbuild@0.27.4)(yaml@2.9.0)) packages/docs: devDependencies: @@ -111,10 +116,10 @@ importers: version: 6.0.3 vite: specifier: ^8.0.14 - version: 8.1.0(@types/node@25.9.4)(esbuild@0.27.4)(yaml@2.9.0) + version: 8.1.0(@types/node@25.9.4)(esbuild@0.27.3)(yaml@2.9.0) vitest: specifier: ^4.1.6 - version: 4.1.9(@types/node@25.9.4)(@vitest/coverage-v8@4.1.2(vitest@4.1.2(@types/node@25.9.4)(jsdom@29.1.1)(vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.4)(yaml@2.9.0))))(jsdom@29.1.1)(vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.4)(yaml@2.9.0)) + version: 4.1.9(@types/node@25.9.4)(@vitest/coverage-v8@4.1.2(vitest@4.1.2(@types/node@25.9.4)(jsdom@29.1.1)(vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.4)(yaml@2.9.0))))(jsdom@29.1.1)(vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.3)(yaml@2.9.0)) packages/landing: devDependencies: @@ -1655,9 +1660,6 @@ packages: any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -2023,11 +2025,6 @@ packages: resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - esquery@1.7.0: resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} @@ -2223,8 +2220,8 @@ packages: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} - handlebars@4.7.8: - resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + handlebars@4.7.9: + resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} engines: {node: '>=0.4.7'} hasBin: true @@ -2434,12 +2431,8 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@3.14.2: - resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} - hasBin: true - - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + js-yaml@5.1.0: + resolution: {integrity: sha512-s8VA5jkR8f22S3NAXmhKPFqGUduqZGlsufabVOgN14iTdw/RXcym7bKkbwjxLK9Yw2lEvvmJjFp119+KPeo8Kg==} hasBin: true jsdom@29.1.1: @@ -3352,9 +3345,6 @@ packages: split2@1.0.0: resolution: {integrity: sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==} - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -3628,14 +3618,6 @@ packages: undici-types@7.24.6: resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} - undici@6.24.1: - resolution: {integrity: sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==} - engines: {node: '>=18.17'} - - undici@7.24.5: - resolution: {integrity: sha512-3IWdCpjgxp15CbJnsi/Y9TCDE7HWVN19j1hmzVhoAkY/+CJx449tVxT5wZc1Gwg8J+P0LWvzlBzxYRnHJ+1i7Q==} - engines: {node: '>=20.18.1'} - undici@7.28.0: resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} engines: {node: '>=20.18.1'} @@ -4010,7 +3992,7 @@ snapshots: '@actions/http-client@4.0.0': dependencies: tunnel: 0.0.6 - undici: 6.24.1 + undici: 7.28.0 '@actions/io@3.0.2': {} @@ -4821,7 +4803,7 @@ snapshots: p-filter: 4.1.0 semantic-release: 25.0.3(typescript@6.0.3) tinyglobby: 0.2.15 - undici: 7.24.5 + undici: 7.28.0 url-join: 5.0.0 transitivePeerDependencies: - supports-color @@ -5098,13 +5080,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.2(vite@8.1.0(@types/node@25.5.2)(esbuild@0.27.3)(yaml@2.9.0))': + '@vitest/mocker@4.1.2(vite@8.1.0(@types/node@25.5.2)(esbuild@0.27.4)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.2 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.1.0(@types/node@25.5.2)(esbuild@0.27.3)(yaml@2.9.0) + vite: 8.1.0(@types/node@25.5.2)(esbuild@0.27.4)(yaml@2.9.0) '@vitest/mocker@4.1.2(vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.4)(yaml@2.9.0))': dependencies: @@ -5114,6 +5096,14 @@ snapshots: optionalDependencies: vite: 8.1.0(@types/node@25.9.4)(esbuild@0.27.4)(yaml@2.9.0) + '@vitest/mocker@4.1.9(vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.3)(yaml@2.9.0))': + dependencies: + '@vitest/spy': 4.1.9 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.1.0(@types/node@25.9.4)(esbuild@0.27.3)(yaml@2.9.0) + '@vitest/mocker@4.1.9(vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.4)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.9 @@ -5337,10 +5327,6 @@ snapshots: any-promise@1.3.0: {} - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - argparse@2.0.1: {} argv-formatter@1.0.0: {} @@ -5501,7 +5487,7 @@ snapshots: dependencies: '@simple-libs/stream-utils': 1.2.0 conventional-commits-filter: 5.0.0 - handlebars: 4.7.8 + handlebars: 4.7.9 meow: 13.2.0 semver: 7.7.4 @@ -5526,7 +5512,7 @@ snapshots: dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 - js-yaml: 4.1.1 + js-yaml: 5.1.0 parse-json: 5.2.0 optionalDependencies: typescript: 6.0.3 @@ -5763,8 +5749,6 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 5.0.1 - esprima@4.0.1: {} - esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -5967,12 +5951,12 @@ snapshots: gray-matter@4.0.3: dependencies: - js-yaml: 3.14.2 + js-yaml: 5.1.0 kind-of: 6.0.3 section-matter: 1.0.0 strip-bom-string: 1.0.0 - handlebars@4.7.8: + handlebars@4.7.9: dependencies: minimist: 1.2.8 neo-async: 2.6.2 @@ -6151,12 +6135,7 @@ snapshots: js-tokens@4.0.0: {} - js-yaml@3.14.2: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - js-yaml@4.1.1: + js-yaml@5.1.0: dependencies: argparse: 2.0.1 @@ -7156,8 +7135,6 @@ snapshots: dependencies: through2: 2.0.5 - sprintf-js@1.0.3: {} - stackback@0.0.2: {} std-env@4.0.0: {} @@ -7412,10 +7389,6 @@ snapshots: undici-types@7.24.6: {} - undici@6.24.1: {} - - undici@7.24.5: {} - undici@7.28.0: {} unicode-emoji-modifier-base@1.0.0: {} @@ -7506,7 +7479,7 @@ snapshots: fsevents: 2.3.3 lightningcss: 1.32.0 - vite@8.1.0(@types/node@25.5.2)(esbuild@0.27.3)(yaml@2.9.0): + vite@8.1.0(@types/node@25.5.2)(esbuild@0.27.4)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -7515,6 +7488,19 @@ snapshots: tinyglobby: 0.2.17 optionalDependencies: '@types/node': 25.5.2 + esbuild: 0.27.4 + fsevents: 2.3.3 + yaml: 2.9.0 + + vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.3)(yaml@2.9.0): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.15 + rolldown: 1.1.3 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 25.9.4 esbuild: 0.27.3 fsevents: 2.3.3 yaml: 2.9.0 @@ -7600,10 +7586,10 @@ snapshots: - typescript - universal-cookie - vitest@4.1.2(@types/node@25.5.2)(jsdom@29.1.1)(vite@8.1.0(@types/node@25.5.2)(esbuild@0.27.3)(yaml@2.9.0)): + vitest@4.1.2(@types/node@25.5.2)(jsdom@29.1.1)(vite@8.1.0(@types/node@25.5.2)(esbuild@0.27.4)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.2 - '@vitest/mocker': 4.1.2(vite@8.1.0(@types/node@25.5.2)(esbuild@0.27.3)(yaml@2.9.0)) + '@vitest/mocker': 4.1.2(vite@8.1.0(@types/node@25.5.2)(esbuild@0.27.4)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.2 '@vitest/runner': 4.1.2 '@vitest/snapshot': 4.1.2 @@ -7620,7 +7606,7 @@ snapshots: tinyexec: 1.0.4 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vite: 8.1.0(@types/node@25.5.2)(esbuild@0.27.3)(yaml@2.9.0) + vite: 8.1.0(@types/node@25.5.2)(esbuild@0.27.4)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 25.5.2 @@ -7656,6 +7642,35 @@ snapshots: transitivePeerDependencies: - msw + vitest@4.1.9(@types/node@25.9.4)(@vitest/coverage-v8@4.1.2(vitest@4.1.2(@types/node@25.9.4)(jsdom@29.1.1)(vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.4)(yaml@2.9.0))))(jsdom@29.1.1)(vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.3)(yaml@2.9.0)): + dependencies: + '@vitest/expect': 4.1.9 + '@vitest/mocker': 4.1.9(vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.3)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.9 + '@vitest/runner': 4.1.9 + '@vitest/snapshot': 4.1.9 + '@vitest/spy': 4.1.9 + '@vitest/utils': 4.1.9 + es-module-lexer: 2.0.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.0.0 + tinybench: 2.9.0 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 8.1.0(@types/node@25.9.4)(esbuild@0.27.3)(yaml@2.9.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 25.9.4 + '@vitest/coverage-v8': 4.1.2(vitest@4.1.2(@types/node@25.9.4)(jsdom@29.1.1)(vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.4)(yaml@2.9.0))) + jsdom: 29.1.1 + transitivePeerDependencies: + - msw + vitest@4.1.9(@types/node@25.9.4)(@vitest/coverage-v8@4.1.2(vitest@4.1.2(@types/node@25.9.4)(jsdom@29.1.1)(vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.4)(yaml@2.9.0))))(jsdom@29.1.1)(vite@8.1.0(@types/node@25.9.4)(esbuild@0.27.4)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.9