Skip to main content

Task Breakdown: SCA Remediation — Upgrade pdfjs-dist 3.11.174 → 4.4.168 (CVE-2024-4367)

Generated from sca-pdfjs-dist-upgrade.md · Epic BOT-4620 · Story BOT-4660 · Task BOT-4661

Reconnaissance findings (Source Verification — all rows filled)

AnchorVerifiedEvidence
pdfjs-dist current version in package.json"pdfjs-dist": "^3.11.174" (dependencies)
Worker init file path and workerSrc assignmentcommon/components/pdf-cover.vue:26"pdfjs-dist/build/pdf.worker.min.js"
Bundler typeNuxt 3 / Vite (confirmed from nuxt.config.ts + devDependencies)
Test runnerVitest ("test": "vitest run" in package.json) — Chunk 4 Jest compat eliminated
All pdfjs-dist import sitesTwo patterns: (1) direct import in pdf-cover.vue; (2) via vue-pdf-embed in SourceDetailFile.vue, detail-drawer.vue, training-source-detail-drawer.vue, learning-source-form.vue
vue-pdf-embed pdfjs-dist versionvue-pdf-embed@2.1.0 bundles pdfjs-dist@^4.4.168 as its own dependencies — those four components are already unaffected by CVE-2024-4367
Duplicate pdfjs-dist in lockfileTwo entries in pnpm-lock.yaml: 3.11.174 (direct) + 4.4.168 (via vue-pdf-embed) — pnpm dedupe after upgrade collapses to one

Key insight: Pinning to ^4.4.168 (not the RFC's conservative 4.2.67) because vue-pdf-embed already resolves 4.4.168 — matching the constraint lets pnpm dedupe collapse to a single version and eliminates any residual worker/API version mismatch risk.


Effort Summary

Phase / AreaFE daysBE daysQA daysTotal
SCA-S01 — Upgrade + patch0.50.51
Grand total0.50.51

Confidence: high. All open questions resolved by reconnaissance. One file has a direct pdfjs-dist import; one test assertion needs updating; Vitest handles ESM natively — no transform work. The vue-pdf-embed-backed viewers are already unaffected.


Task 1: [FE] Upgrade pdfjs-dist + patch pdf-cover.vue worker init (SCA-S01)

A user opening a PDF in the chatbot is no longer exposed to CVE-2024-4367 arbitrary JS execution via the pdf-cover thumbnail renderer.

Jira: BOT-4661 · split from BOT-4660

Status: ✅ Actionable

Design reference: N/A — security remediation, no visual change.

What to build

Bump pdfjs-dist from 3.11.174 to 4.4.168 (matching vue-pdf-embed's own dep, enabling dedup to one resolved version), update the single workerSrc line in pdf-cover.vue from .js.mjs, update the one test assertion that checks the extension, and verify clean audit + build.

Implementation Plan

ActionFileWhat changes
modifypackage.jsonpdfjs-dist specifier ^3.11.174^4.4.168
regeneratedpnpm-lock.yamlpdfjs-dist collapses from two entries (3.11.174 + 4.4.168) to one (4.4.168) after dedupe
extendcommon/components/pdf-cover.vueLine 26: pdf.worker.min.jspdf.worker.min.mjs
extendtests/unit/common/components/pdf-cover.test.tsLine 84: assertion updated from "pdf.worker.min.js" to "pdf.worker.min.mjs"

Implementation steps

  1. Verify current state — Open common/components/pdf-cover.vue and confirm line 26 reads "pdfjs-dist/build/pdf.worker.min.js". Open tests/unit/common/components/pdf-cover.test.ts and confirm line 84 reads .toContain("pdf.worker.min.js").

  2. Write failing test (red) — In pdf-cover.test.ts line 84, change:

    // BEFORE
    expect(GlobalWorkerOptions.workerSrc).toContain("pdf.worker.min.js");
    // AFTER
    expect(GlobalWorkerOptions.workerSrc).toContain("pdf.worker.min.mjs");

    Run pnpm test -- tests/unit/common/components/pdf-cover.test.ts — the sets workerSrc on mount test should now fail (still references .js in source).

  3. Upgrade the package:

    pnpm add pdfjs-dist@^4.4.168

    Confirm package.json now shows "pdfjs-dist": "^4.4.168".

  4. Deduplicate lockfile:

    pnpm dedupe
    grep 'pdfjs-dist' pnpm-lock.yaml | grep 'version'
    # Expected: single entry at 4.4.168
  5. Patch worker init — In common/components/pdf-cover.vue line 26, change:

    // BEFORE (v3)
    pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
    "pdfjs-dist/build/pdf.worker.min.js",
    import.meta.url,
    ).href;
    // AFTER (v4)
    pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
    "pdfjs-dist/build/pdf.worker.min.mjs",
    import.meta.url,
    ).href;
  6. Go green — Run pnpm test -- tests/unit/common/components/pdf-cover.test.ts — all 9 tests should pass.

  7. Quality gate:

    pnpm test
    pnpm build
    pnpm audit 2>&1 | grep -i 'CVE-2024-4367' || echo "CVE-2024-4367 not found — clean"
    grep -r 'pdf.worker.min.js' src/ # Expected: 0 matches

Acceptance criteria

  • package.json shows "pdfjs-dist": "^4.4.168"
  • pnpm-lock.yaml resolves exactly one pdfjs-dist version (4.4.168) — no duplicate entries
  • common/components/pdf-cover.vue workerSrc uses pdf.worker.min.mjs
  • pnpm audit does NOT list CVE-2024-4367
  • pnpm test exits 0 (all 9 pdf-cover.test.ts tests pass)
  • pnpm build exits 0 with no PDF.js-related errors
  • No console errors on opening a PDF in the browser (worker version mismatch)

Test strategy

The existing pdf-cover.test.ts mocks pdfjs-dist entirely via vi.mock("pdfjs-dist", ...) — Vitest handles ESM natively, so no transform config is needed. The only change is the one assertion at line 84 that checks workerSrc contains the worker filename. All other 8 test cases (rendering, canvas sizing, error handling) are unaffected.

Effort estimate

DisciplineDays
Frontend0.5
Backend
QA0.5
Total1

Assumptions: vue-pdf-embed-backed components untouched (they already use pdfjs-dist 4.4.168 internally); Vitest handles ESM natively — no Jest transform work; no Vite worker plugin config change required (Nuxt 3's Vite handles new URL(…, import.meta.url) natively).

Run to verify

pnpm test -- tests/unit/common/components/pdf-cover.test.ts && pnpm build && pnpm audit 2>&1 | grep -i CVE-2024-4367 || echo "CVE-2024-4367 not found — clean"

Depends on

None — fully self-contained. All OQs resolved by reconnaissance.


Ordering rationale

  • Single story, single PR — no ordering decisions needed.
  • Start directly at the package upgrade; Chunk 0 repo grounding from the RFC is already done by reconnaissance above.
  • Pinning ^4.4.168 over the RFC's conservative ^4.2.67vue-pdf-embed@2.1.0 already resolves pdfjs-dist@4.4.168 as a transitive dep; matching the constraint lets pnpm dedupe collapse to one version, eliminating any residual worker/API version mismatch risk.
  • Chunk 4 (Jest ESM compat) eliminated entirely — test runner is Vitest.

Skipped stories

Story / ChunkReason
Chunk 4 — Jest ESM compatNot applicable — test runner is Vitest, which handles ESM natively
vue-pdf-embed-backed components (SourceDetailFile.vue, detail-drawer.vue, training-source-detail-drawer.vue, learning-source-form.vue)No action needed — vue-pdf-embed@2.1.0 already pins pdfjs-dist@^4.4.168 as its own dependencies entry; CVE-2024-4367 is already closed for those surfaces