diff --git a/.github/workflows/dependency-audit.yml b/.github/workflows/dependency-audit.yml new file mode 100644 index 0000000..abfecbf --- /dev/null +++ b/.github/workflows/dependency-audit.yml @@ -0,0 +1,44 @@ +name: Dependency audit + +# Executable docs tooling (snippet compiler, playground, quickstart harnesses) +# pulls in the chain SDKs as production dependencies. This job enforces the +# policy in DEPENDENCY-POLICY.md: no high or critical advisories on any +# production dependency path. Moderate findings may be recorded in +# `pnpm.auditConfig.ignoreGhsas` in package.json with a documented reason. +# +# The weekly run re-checks against the live advisory database so a newly +# disclosed advisory fails the build even without a dependency change. + +on: + pull_request: + push: + branches: + - develop + - main + schedule: + - cron: "0 6 * * 1" + +jobs: + audit: + name: Production dependency audit + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Fail on high or critical advisories + run: pnpm audit --prod --audit-level high diff --git a/DEPENDENCY-POLICY.md b/DEPENDENCY-POLICY.md new file mode 100644 index 0000000..8c878c2 --- /dev/null +++ b/DEPENDENCY-POLICY.md @@ -0,0 +1,50 @@ +# Dependency advisory policy — docs tooling + +The documentation in this repository is built and verified by executable +tooling: the TypeScript snippet compiler, the interactive playground and its +Playwright smoke tests, the Python and Rust quickstart harnesses, and the +`@wraith-protocol/sdk` chain SDKs they load. Those packages are declared as +production dependencies because the checks run against them exactly as a reader +would consume them, so they are a supply-chain surface that is held to the same +bar as shipped code. + +## Requirements + +- **No high or critical advisories** on any production dependency path. This is + enforced by the [`Dependency audit`](.github/workflows/dependency-audit.yml) + workflow, which runs `pnpm audit --prod --audit-level high` on every pull + request, on every push to `develop` and `main`, and weekly against the live + advisory database. A high or critical finding blocks merge until the + dependency is upgraded or the vulnerable path is removed. Do not waive it. +- **Moderate and low findings** are reviewed case by case. A finding may be + recorded in `pnpm.auditConfig.ignoreGhsas` in `package.json` only when both of + the following hold: + 1. no patched release exists that is compatible with the pinned parent ranges + and the SDK's declared peer dependencies, and + 2. the vulnerable code path is not reachable from the docs tooling. + + Every entry must be justified in the pull request that adds it. Remove the + entry as soon as the parent dependency ships a compatible fix. +- **Fixes prefer upgrades.** `pnpm.overrides` is used only to lift a transitive + dependency to a patched version when its parent has not released one. An + override is a temporary bridge: drop it once the parent resolves the fix on + its own. + +## Accepted findings + +| Advisory | Package | Path | Why it is accepted | +|---|---|---|---| +| [GHSA-528h-pc64-c93x](https://github.com/advisories/GHSA-528h-pc64-c93x) | `stream-json` | `@solana/web3.js` → `jayson` | Patched releases (`>=3.6.0`) are ESM-only and no longer expose the `stream-json/streamers/StreamValues` and `stream-json/utils/Verifier` subpaths that `jayson@4` `require()`s, so there is no compatible fix. Affects the filter operators, which `jayson` does not use. | +| [GHSA-hqr4-qq8f-hg3x](https://github.com/advisories/GHSA-hqr4-qq8f-hg3x) | `stream-json` | `@solana/web3.js` → `jayson` | Same compatibility constraint as above. Affects the JSONC parser and verifier, which `jayson` does not use. | +| [GHSA-mjw6-4jj6-33hc](https://github.com/advisories/GHSA-mjw6-4jj6-33hc) | `stream-json` | `@solana/web3.js` → `jayson` | Same compatibility constraint as above. Affects the `Assembler` convenience stream, which `jayson` does not use. | + +The high-severity Stellar path findings (`axios`, `toml`) and the Solana path +`uuid` finding are fixed by the `pnpm.overrides` entries in `package.json`; see +the pull request that added them for the resolution details. + +## Running the check locally + +```bash +pnpm install --frozen-lockfile +pnpm audit --prod --audit-level high +``` diff --git a/package.json b/package.json index d34b957..8d2def8 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,8 @@ "test": "npm run check:snippets && npm run check:nav-coverage && npm run check:contract-registry && npm run check:compatibility-matrix && npm run test:redirects-and-anchors" }, "dependencies": { - "@solana/web3.js": "^1.95.0", - "@stellar/stellar-sdk": "^13.1.0", + "@solana/web3.js": "^1.99.0", + "@stellar/stellar-sdk": "^13.3.0", "@wraith-protocol/sdk": "1.4.5" }, "devDependencies": { @@ -38,5 +38,19 @@ "js-yaml": "4.3.2", "tsx": "^4.19.2", "typescript": "^5.7.2" + }, + "pnpm": { + "overrides": { + "axios@<1.20.0": ">=1.20.0", + "toml@<4.2.0": "^4.2.0", + "uuid@<11.1.1": "^11.1.1" + }, + "auditConfig": { + "ignoreGhsas": [ + "GHSA-528h-pc64-c93x", + "GHSA-hqr4-qq8f-hg3x", + "GHSA-mjw6-4jj6-33hc" + ] + } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bbbd159..a43c3d3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,19 +4,24 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + axios@<1.20.0: '>=1.20.0' + toml@<4.2.0: ^4.2.0 + uuid@<11.1.1: ^11.1.1 + importers: .: dependencies: '@solana/web3.js': - specifier: ^1.95.0 - version: 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + specifier: ^1.99.0 + version: 1.99.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) '@stellar/stellar-sdk': - specifier: ^13.1.0 + specifier: ^13.3.0 version: 13.3.0 '@wraith-protocol/sdk': specifier: 1.4.5 - version: 1.4.5(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6))(@stellar/stellar-sdk@13.3.0)(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + version: 1.4.5(@solana/web3.js@1.99.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6))(@stellar/stellar-sdk@13.3.0)(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) devDependencies: '@playwright/test': specifier: ^1.49.1 @@ -27,12 +32,12 @@ importers: '@types/node': specifier: ^22.10.2 version: 22.20.1 - tsx: - specifier: ^4.19.2 - version: 4.23.0 js-yaml: specifier: 4.3.2 version: 4.3.2 + tsx: + specifier: ^4.19.2 + version: 4.23.0 typescript: specifier: ^5.7.2 version: 5.9.3 @@ -236,27 +241,36 @@ packages: resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} engines: {node: '>=5.10'} - '@solana/codecs-core@2.3.0': - resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} + '@solana/codecs-core@5.5.1': + resolution: {integrity: sha512-TgBt//bbKBct0t6/MpA8ElaOA3sa8eYVvR7LGslCZ84WiAwwjCY0lW/lOYsFHJQzwREMdUyuEyy5YWBKtdh8Rw==} engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5.3.3' + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true - '@solana/codecs-numbers@2.3.0': - resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} + '@solana/codecs-numbers@5.5.1': + resolution: {integrity: sha512-rllMIZAHqmtvC0HO/dc/21wDuWaD0B8Ryv8o+YtsICQBuiL/0U4AGwH7Pi5GNFySYk0/crSuwfIqQFtmxNSPFw==} engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5.3.3' + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true - '@solana/errors@2.3.0': - resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} + '@solana/errors@5.5.1': + resolution: {integrity: sha512-vFO3p+S7HoyyrcAectnXbdsMfwUzY2zYFUc2DEe5BwpiE9J1IAxPBGjOWO6hL1bbYdBrlmjNx8DXCslqS+Kcmg==} engines: {node: '>=20.18.0'} hasBin: true peerDependencies: - typescript: '>=5.3.3' + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true - '@solana/web3.js@1.98.4': - resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==} + '@solana/web3.js@1.99.0': + resolution: {integrity: sha512-QZYQ2T1z6xWisoyALPq25i/QZTsRlM02BABtAsfaQ1p8wX4SdTfxrKTRue/ZZqrhNVh5oL7T/DUFiTS9DRgxow==} '@stellar/js-xdr@3.1.2': resolution: {integrity: sha512-VVolPL5goVEIsvuGqDc5uiKxV03lzfWdvYg1KikvwheDmTBO68CKDji3bAZ/kppZrx5iTA8z3Ld5yuytcvhvOQ==} @@ -324,18 +338,18 @@ packages: resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} engines: {node: '>= 8.0.0'} - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axios@1.18.1: - resolution: {integrity: sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==} + axios@1.20.0: + resolution: {integrity: sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg==} bare-addon-resolve@1.10.0: resolution: {integrity: sha512-sSd0jieRJlDaODOzj0oe0RjFVC1QI0ZIjGIdPkbrTXsdVVtENg14c+lHHAhHwmWCZ2nQlMhy8jA3Y5LYPc/isA==} @@ -369,8 +383,8 @@ packages: bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} - bn.js@5.2.4: - resolution: {integrity: sha512-QL7sb18rJ1PbdsKsqPA0guxL563vIMwRHgzNrW/uzQuRGN1Cjqd/wonUBAVqHox9KwzHA6vCbM0lXx3k4iQMow==} + bn.js@5.2.5: + resolution: {integrity: sha512-Vq886eXykuP5E6HcKSSStP3bJgrE6In5WKxVUvJ8XGpWWYs2xZHWqUwzCtGgEtBcxyd57KBFDPFoUfNzdaHCNg==} borsh@0.7.0: resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} @@ -405,8 +419,8 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} - commander@14.0.3: - resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + commander@14.0.2: + resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} engines: {node: '>=20'} commander@2.20.3: @@ -687,8 +701,9 @@ packages: resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} engines: {node: '>= 0.4'} - toml@3.0.0: - resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + toml@4.3.0: + resolution: {integrity: sha512-lVb8X9BsPVuH0M4BKeS91tXAmJvCjQ5UIyAbQFaxkKGyUFK2RPkhwaFSQH8vbpl1d23eu/IBH+dwVMHWaq9A5A==} + engines: {node: '>=20'} tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -723,13 +738,12 @@ packages: resolution: {integrity: sha512-q3l3P9UtEEiAHcsgsqTgf9PPjctrDWoIXW3NpOHFdRDbLvu4DLIcxHangJ4RLrWkBcKjmcs/6NkerI8T/rE4LA==} engines: {node: '>=6.14.2'} - uuid@14.0.1: - resolution: {integrity: sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==} + uuid@11.1.1: + resolution: {integrity: sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==} hasBin: true - uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). + uuid@14.0.1: + resolution: {integrity: sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==} hasBin: true viem@2.54.6: @@ -891,32 +905,35 @@ snapshots: dependencies: buffer: 6.0.3 - '@solana/codecs-core@2.3.0(typescript@5.9.3)': + '@solana/codecs-core@5.5.1(typescript@5.9.3)': dependencies: - '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + optionalDependencies: typescript: 5.9.3 - '@solana/codecs-numbers@2.3.0(typescript@5.9.3)': + '@solana/codecs-numbers@5.5.1(typescript@5.9.3)': dependencies: - '@solana/codecs-core': 2.3.0(typescript@5.9.3) - '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/codecs-core': 5.5.1(typescript@5.9.3) + '@solana/errors': 5.5.1(typescript@5.9.3) + optionalDependencies: typescript: 5.9.3 - '@solana/errors@2.3.0(typescript@5.9.3)': + '@solana/errors@5.5.1(typescript@5.9.3)': dependencies: chalk: 5.6.2 - commander: 14.0.3 + commander: 14.0.2 + optionalDependencies: typescript: 5.9.3 - '@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)': + '@solana/web3.js@1.99.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)': dependencies: '@babel/runtime': 7.29.7 '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 - '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 5.5.1(typescript@5.9.3) agentkeepalive: 4.6.0 - bn.js: 5.2.4 + bn.js: 5.2.5 borsh: 0.7.0 bs58: 4.0.1 buffer: 6.0.3 @@ -949,12 +966,12 @@ snapshots: '@stellar/stellar-sdk@13.3.0': dependencies: '@stellar/stellar-base': 13.1.0 - axios: 1.18.1 + axios: 1.20.0 bignumber.js: 9.3.1 eventsource: 2.0.2 feaxios: 0.0.23 randombytes: 2.1.0 - toml: 3.0.0 + toml: 4.3.0 urijs: 1.19.11 transitivePeerDependencies: - bare-url @@ -987,13 +1004,13 @@ snapshots: dependencies: '@types/node': 22.20.1 - '@wraith-protocol/sdk@1.4.5(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6))(@stellar/stellar-sdk@13.3.0)(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)': + '@wraith-protocol/sdk@1.4.5(@solana/web3.js@1.99.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6))(@stellar/stellar-sdk@13.3.0)(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)': dependencies: '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 viem: 2.54.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) optionalDependencies: - '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@solana/web3.js': 1.99.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) '@stellar/stellar-sdk': 13.3.0 transitivePeerDependencies: - bufferutil @@ -1015,15 +1032,15 @@ snapshots: dependencies: humanize-ms: 1.2.1 - asynckit@0.4.0: {} - argparse@2.0.1: {} + asynckit@0.4.0: {} + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 - axios@1.18.1: + axios@1.20.0: dependencies: follow-redirects: 1.16.0 form-data: 4.0.6 @@ -1057,11 +1074,11 @@ snapshots: bignumber.js@9.3.1: {} - bn.js@5.2.4: {} + bn.js@5.2.5: {} borsh@0.7.0: dependencies: - bn.js: 5.2.4 + bn.js: 5.2.5 bs58: 4.0.1 text-encoding-utf-8: 1.0.2 @@ -1102,7 +1119,7 @@ snapshots: dependencies: delayed-stream: 1.0.0 - commander@14.0.3: {} + commander@14.0.2: {} commander@2.20.3: {} @@ -1291,18 +1308,18 @@ snapshots: isomorphic-ws: 4.0.1(ws@7.5.11(bufferutil@4.1.0)(utf-8-validate@6.0.6)) json-stringify-safe: 5.0.1 stream-json: 1.9.1 - uuid: 8.3.2 + uuid: 11.1.1 ws: 7.5.11(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - utf-8-validate - json-stringify-safe@5.0.1: {} - js-yaml@4.3.2: dependencies: argparse: 2.0.1 + json-stringify-safe@5.0.1: {} + math-intrinsics@1.1.0: {} mime-db@1.52.0: {} @@ -1411,7 +1428,7 @@ snapshots: safe-buffer: 5.2.1 typed-array-buffer: 1.0.3 - toml@3.0.0: {} + toml@4.3.0: {} tr46@0.0.3: {} @@ -1442,9 +1459,9 @@ snapshots: node-gyp-build: 4.8.4 optional: true - uuid@14.0.1: {} + uuid@11.1.1: {} - uuid@8.3.2: {} + uuid@14.0.1: {} viem@2.54.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6): dependencies: