codeburn/package.json
iamtoruk 09965f93ae fix(dsh): cap zstd decode, coerce usage fields, scope the snap read
Security audit follow-ups on the DeepSeek Harness provider.

- **Decompression bomb.** Every zstd frame was decoded with no output bound, so
  a 16 KB crafted log expanded to ~916 MB of RSS (a 65 KB one declares 2 GB).
  Each frame now decodes under a 64 MB per-call cap, and the caps chain into a
  running per-file budget of MAX_SESSION_FILE_BYTES: a frame is given only the
  bytes the file has left, so node throws ERR_BUFFER_TOO_LARGE without
  allocating past the cap. The throw propagates out of the existing skip path,
  which discards the whole file rather than counting the frames read before the
  bomb, so a crafted tail cannot poison a partial total. The discovery header
  read takes the same per-frame cap. Measured on a 65 KB / 2 GB bomb: 916 MB
  -> 67 MB peak, zero calls emitted, one notice.
  Lines are still materialized eagerly; the byte budget bounds that, and making
  the read lazy would change readEventLines' contract for no further bound.
- **Usage type confusion.** Token fields were read with `?? 0` and never
  type-checked, so a string or array inputTokens flowed into the global totals
  and the persisted cache, where `0 + [1, 2]` becomes "01,2". They now go
  through numberOrZero (copilot.ts semantics: finite, positive, else 0).
  All-zero calls are still skipped.
- **Snap over-scope.** The personal-files read entry is `$HOME/.dsh/sessions`
  rather than all of `$HOME/.dsh`; the provider reads nothing else.
- **Third-party notice.** scanZstdFrames is transcribed from
  @deepseek-ai/dsh-session-persistence-jsonl. The published npm package is
  BSD-3-Clause (Copyright (c) 2026, DeepSeek) while the monorepo source
  declares MIT for the same package; THIRD_PARTY_NOTICES.md reproduces the
  stricter of the two and ships via package.json `files`.
2026-08-17 17:28:41 -07:00

79 lines
2.4 KiB
JSON

{
"name": "codeburn",
"version": "0.9.20",
"description": "See where your AI spend goes - by task, tool, model, and project",
"type": "module",
"main": "./dist/cli.js",
"bin": {
"codeburn": "dist/cli.js"
},
"files": [
"dist",
"THIRD_PARTY_NOTICES.md",
"!dist/parse-worker.js.map"
],
"scripts": {
"bundle-litellm": "node scripts/bundle-litellm.mjs",
"build": "node scripts/bundle-litellm.mjs && tsup && node -e \"const fs=require('fs'); fs.copyFileSync('src/cli.ts','dist/cli.js'); fs.chmodSync('dist/cli.js',0o755)\" && npm run build:dash",
"build:cli": "tsup && node -e \"const fs=require('fs'); fs.copyFileSync('src/cli.ts','dist/cli.js'); fs.chmodSync('dist/cli.js',0o755)\"",
"build:dash": "cd dash && npm install --no-audit --no-fund --silent && npm run build",
"dev": "NODE_OPTIONS=--no-deprecation tsx src/cli.ts",
"test": "vitest run tests --exclude \"tests/cache-refresh-lock*\"",
"test:locks": "vitest run tests/cache-refresh-lock.test.ts tests/cache-refresh-lock-corrupt-body.test.ts tests/cache-refresh-lock-process.test.ts --poolOptions.forks.singleFork=true",
"test:watch": "vitest tests --exclude \"tests/cache-refresh-lock*\"",
"prepublishOnly": "npm run build"
},
"keywords": [
"claude-code",
"cursor",
"codex",
"kimi",
"devin",
"ibm-bob",
"opencode",
"pi",
"codebuff",
"codewhale",
"dsh",
"ai-coding",
"token-usage",
"cost-tracking",
"observability",
"developer-tools"
],
"engines": {
"node": ">=22.13.0"
},
"author": "AgentSeal <hello@agentseal.org>",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/getagentseal/codeburn.git"
},
"bugs": {
"url": "https://github.com/getagentseal/codeburn/issues"
},
"homepage": "https://github.com/getagentseal/codeburn#readme",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.29.0",
"bonjour-service": "^1.4.1",
"chalk": "^5.4.1",
"commander": "^13.1.0",
"ink": "^7.0.0",
"react": "^19.2.5",
"selfsigned": "^5.5.0",
"strip-ansi": "^7.2.0",
"undici": "^7.27.2",
"zod": "^3.25.76"
},
"devDependencies": {
"@types/node": "^22.19.17",
"@types/react": "^19.2.14",
"@types/selfsigned": "^2.0.4",
"playwright": "^1.61.1",
"tsup": "^8.4.0",
"tsx": "^4.19.0",
"typescript": "^5.8.0",
"vitest": "^3.1.0"
}
}