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)
| Anchor | Verified | Evidence |
|---|---|---|
pdfjs-dist current version in package.json | ✅ | "pdfjs-dist": "^3.11.174" (dependencies) |
Worker init file path and workerSrc assignment | ✅ | common/components/pdf-cover.vue:26 — "pdfjs-dist/build/pdf.worker.min.js" |
| Bundler type | ✅ | Nuxt 3 / Vite (confirmed from nuxt.config.ts + devDependencies) |
| Test runner | ✅ | Vitest ("test": "vitest run" in package.json) — Chunk 4 Jest compat eliminated |
| All pdfjs-dist import sites | ✅ | Two 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 version | ✅ | vue-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 lockfile | ✅ | Two 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 / Area | FE days | BE days | QA days | Total |
|---|---|---|---|---|
| SCA-S01 — Upgrade + patch | 0.5 | — | 0.5 | 1 |
| Grand total | 0.5 | — | 0.5 | 1 |
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
| Action | File | What changes |
|---|---|---|
| modify | package.json | pdfjs-dist specifier ^3.11.174 → ^4.4.168 |
| regenerated | pnpm-lock.yaml | pdfjs-dist collapses from two entries (3.11.174 + 4.4.168) to one (4.4.168) after dedupe |
| extend | common/components/pdf-cover.vue | Line 26: pdf.worker.min.js → pdf.worker.min.mjs |
| extend | tests/unit/common/components/pdf-cover.test.ts | Line 84: assertion updated from "pdf.worker.min.js" to "pdf.worker.min.mjs" |
Implementation steps
-
Verify current state — Open
common/components/pdf-cover.vueand confirm line 26 reads"pdfjs-dist/build/pdf.worker.min.js". Opentests/unit/common/components/pdf-cover.test.tsand confirm line 84 reads.toContain("pdf.worker.min.js"). -
Write failing test (red) — In
pdf-cover.test.tsline 84, change:// BEFOREexpect(GlobalWorkerOptions.workerSrc).toContain("pdf.worker.min.js");// AFTERexpect(GlobalWorkerOptions.workerSrc).toContain("pdf.worker.min.mjs");Run
pnpm test -- tests/unit/common/components/pdf-cover.test.ts— thesets workerSrc on mounttest should now fail (still references.jsin source). -
Upgrade the package:
pnpm add pdfjs-dist@^4.4.168Confirm
package.jsonnow shows"pdfjs-dist": "^4.4.168". -
Deduplicate lockfile:
pnpm dedupegrep 'pdfjs-dist' pnpm-lock.yaml | grep 'version'# Expected: single entry at 4.4.168 -
Patch worker init — In
common/components/pdf-cover.vueline 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; -
Go green — Run
pnpm test -- tests/unit/common/components/pdf-cover.test.ts— all 9 tests should pass. -
Quality gate:
pnpm testpnpm buildpnpm 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.jsonshows"pdfjs-dist": "^4.4.168" -
pnpm-lock.yamlresolves exactly onepdfjs-distversion (4.4.168) — no duplicate entries -
common/components/pdf-cover.vueworkerSrcusespdf.worker.min.mjs -
pnpm auditdoes NOT list CVE-2024-4367 -
pnpm testexits 0 (all 9pdf-cover.test.tstests pass) -
pnpm buildexits 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
| Discipline | Days |
|---|---|
| Frontend | 0.5 |
| Backend | — |
| QA | 0.5 |
| Total | 1 |
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 handlesnew 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.168over the RFC's conservative^4.2.67—vue-pdf-embed@2.1.0already resolvespdfjs-dist@4.4.168as a transitive dep; matching the constraint letspnpm dedupecollapse 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 / Chunk | Reason |
|---|---|
| Chunk 4 — Jest ESM compat | Not 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 |