Skip to content

Commit d403e9c

Browse files
Marfuenclaude
andauthored
fix(deps): remediate dependency security vulnerabilities (165→16, 4 critical→0) (#3406)
* fix(deps): remediate dependency security vulnerabilities (165 -> 16) Comprehensive dependency-security pass. Reduces `bun audit` from 165 findings (4 critical / 58 high) to 16 (0 critical / 10 high / 3 moderate / 3 low). All changes stay within declared version ranges; bun.lock is a clean regeneration. Direct bumps (vulnerable instance was the direct dep): - better-auth 1.4.22 -> ^1.6.13 (CVE-2026-53512, CVSS 9.1 OAuth refresh-token replay; mcp/oidcProvider plugin is enabled in apps/api) - next -> ^16.2.6 (middleware/proxy bypass, SSRF, DoS) - axios -> ^1.16.0 (proxy-auth credential leak, prototype pollution) - vitest -> ^3.2.6, vite -> ^6.4.3, turbo -> ^2.10.5 Dead-dep removal (unused, referenced by no script): - gitmoji -> cascade-drops request, tough-cookie@2.5.0, tar@2.2.2, node-gyp@3 - semantic-release-discord + -notifier -> drops discord.js/@discordjs/rest (which pinned undici@6 and blocked patching it). The real release->Discord notification is a separate webhook GitHub Action (no npm deps) - untouched. Parent bumps (newer parent pulls a patched child): - @browserbasehq/stagehand -> ^3.7.0 (drops langchain + langsmith) - @nestjs/swagger -> ^11.4.5 (patched js-yaml 4.3.0) Overrides for transitive vulns (backcompat-safe, verified): - axios, form-data, ws, semver, hono, @hono/node-server, multer, systeminformation, tmp, dompurify, ip-address, postcss, prismjs, qs, effect, protobufjs, linkify-it, mermaid, shell-quote, vite, @opentelemetry/core, @sigstore/core, markdown-it, @babel/core - @tiptap/* pinned 3.22.1 (lockstep; the lockfile regen floated the transitive @tiptap/* apart from @tiptap/react@3.22.1) undici NOT force-overridden across majors (discord.js path removed; the lockfile regen floats v6->6.27.0 and v7->7.28.0 within ranges instead). Verified: full `turbo build` (20/20) + typecheck (0 production errors) across all apps; apps/api Dockerfile.multistage builds clean and boots past module-load (better-auth 1.6 loads; stops only at the expected SECRET_KEY env guard). openapi.json intentionally untouched (no API files changed). Remaining 16 are all dev/build-time or no-upstream-fix: tar (electron-builder/giget/npm-bundled), minimatch (npm-bundled), esbuild (dev-server only), uuid (exceljs, no v8 fix), sigstore (release CI), cookie (disjoint majors), @ai-sdk/provider-utils (low, via stagehand). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(app): make permissions readonly-compatible for better-auth 1.6 better-auth 1.6 types role `statements` as readonly tuples (ExactRoleStatements = { readonly [P]: readonly [...] }), so casting `role.statements as Record<string, string[]>` (mutable) is an invalid conversion and fails `next build`'s TypeScript check on Vercel: Type 'readonly ["read"]' cannot be assigned to the mutable type 'string[]' Widen `mergePermissions`'s `source` param to `Record<string, readonly string[]>` (it only reads, never mutates) and cast to the readonly type. Verified against better-auth@1.6.23 dist types; the only `.statements` cast in the app (other Record<string,string[]> casts are on JSON/any). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 7577a37 commit d403e9c

5 files changed

Lines changed: 1665 additions & 1742 deletions

File tree

‎apps/api/package.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,15 @@
6161
"@aws-sdk/lib-storage": "3.1013.0",
6262
"@aws-sdk/s3-request-presigner": "3.1013.0",
6363
"@browserbasehq/sdk": "2.6.0",
64-
"@browserbasehq/stagehand": "^3.2.1",
64+
"@browserbasehq/stagehand": "^3.7.0",
6565
"@inference/tracing": "^0.0.21",
6666
"@maced/api-client": "^0.9.2",
6767
"@mendable/firecrawl-js": "^4.9.3",
6868
"@nestjs/common": "^11.0.1",
6969
"@nestjs/config": "^4.0.2",
7070
"@nestjs/core": "^11.0.1",
7171
"@nestjs/platform-express": "^11.1.5",
72-
"@nestjs/swagger": "^11.2.0",
72+
"@nestjs/swagger": "^11.4.5",
7373
"@nestjs/throttler": "^6.5.0",
7474
"@prisma/adapter-pg": "7.6.0",
7575
"@prisma/client": "7.6.0",

‎apps/app/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"@aws-sdk/s3-request-presigner": "3.1013.0",
1919
"@azure/core-rest-pipeline": "^1.21.0",
2020
"@browserbasehq/sdk": "2.6.0",
21-
"@browserbasehq/stagehand": "^3.0.5",
21+
"@browserbasehq/stagehand": "^3.7.0",
2222
"@date-fns/tz": "^1.2.0",
2323
"@dnd-kit/core": "^6.3.1",
2424
"@dnd-kit/modifiers": "^9.0.0",

‎apps/app/src/lib/permissions.ts‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,15 +230,18 @@ export function resolveBuiltInPermissions(roleString: string | null | undefined)
230230
if (BUILT_IN_ROLE_NAMES.includes(roleName)) {
231231
const role = allRoles[roleName as RoleName];
232232
if (role) {
233-
mergePermissions(combined, role.statements as Record<string, string[]>);
233+
mergePermissions(combined, role.statements as Record<string, readonly string[]>);
234234
}
235235
}
236236
}
237237

238238
return { permissions: combined, customRoleNames };
239239
}
240240

241-
export function mergePermissions(target: UserPermissions, source: Record<string, string[]>): void {
241+
export function mergePermissions(
242+
target: UserPermissions,
243+
source: Record<string, readonly string[]>,
244+
): void {
242245
for (const [resource, actions] of Object.entries(source)) {
243246
if (!target[resource]) {
244247
target[resource] = [];

0 commit comments

Comments
 (0)