You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
security(pdf): remediate GHSA-hq66-cqwq-w95j before v1.4 (pdfjs-dist 5.7.284 in affected range) #121
pdfjs-dist is pinned in dependencies and is the parsing engine for the app's core input, so a
known-high advisory cannot ship in v1.4. The library is affected; the reachability of the exploit
in KnowNote is a separate question, and the evidence below says it is not currently reachable —
which is why this is a scheduled, deliberate upgrade rather than a fire. It is still a blocker,
because "not reachable" here rests on our own call sites rather than on anything the library
guarantees.
High — CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
Affected
pdfjs-dist >=5.6.83 <6.2.108
Fixed
6.2.108
Installed here
5.7.284 — inside the affected range (package.json declares ^5.4.530; the lockfile resolves to 5.7.284)
Advisory impact statement, verbatim:
If PDF.js is used to load a malicious PDF, and PDF.js is configured with enableScripting set to
true (which is the default value) and no CSP for disallowing script-src, unrestricted
attacker-controlled JavaScript will be executed in the context of the hosting domain.
Official workarounds: "Set enableScripting to false or set a CSP."
Exploit conditions in KnowNote — checked, not assumed
Both PDF paths were inspected. Neither opts into the vulnerable path, and neither instantiates the
component that would exercise it:
Path
Entry point
Options passed
What it uses the document for
main
src/main/services/loaders/PdfLoader.ts:68
getDocument({ data, password }) — no enableScripting
The advisory's prerequisite is enableScripting: trueplus the code that acts on it:
enableScripting is consumed by AnnotationLayer (annotation JS actions) and by the viewer's PDFScriptingManager, which is what actually executes document JavaScript.
KnowNote builds no AnnotationLayer and imports no pdfjs-dist/web/*. In the installed
package, PDFScriptingManager appears only in web/pdf_viewer.mjs — grep -c PDFScriptingManager
against the API build build/pdf.mjs is 0.
Bare pdfjs-dist resolves to main: build/pdf.mjs, i.e. the API build, for the renderer; the
main process imports pdfjs-dist/legacy/build/pdf.mjs. The only other import is the parsing
worker (build/pdf.worker.min.mjs?url).
The API build contains no eval() / new Function() scripting primitive: the annotation layer's _bindJSAction only binds DOM listeners that dispatch into a sandbox the viewer is expected to
provide.
Conclusion: the stated exploit conditions are not met on either path today. This must be
re-verified as part of this issue, because the conclusion depends on our call sites: adding an
annotation layer, or the #71 renderer-side PDF spike, would put the vulnerable code back in scope.
Acceptance
Exploit conditions re-confirmed on both paths (main PdfLoader, renderer PdfSourceReader) and the finding recorded, so the reasoning survives the next reader
enableScripting: false passed explicitly on both getDocument calls — corrected, this was not implementable.enableScripting is declared on AnnotationLayer / AnnotationLayerBuilder / PDFViewer, and is not a DocumentInitParameters member, so TypeScript rejects it on getDocument (TS2353). The advisory's workaround targets the viewer, which this app does not use, so there is no switch to flip at our call sites.
The mitigation is therefore structural, and is now a CI-enforced invariant rather than a one-time inspection: test/pdfjsScriptingBoundary.test.ts fails if anything imports the viewer build (where PDFScriptingManager lives), constructs the annotation layer or scripting manager, or sets enableScripting: true — with a self-check so it cannot pass by scanning nothing.
Evaluate whether a CSP is additionally warranted for the reader, given the reader renders untrusted documents in the renderer process
Upgrade to pdfjs-dist >=6.2.108; confirm 6.x is the first fixed line and record the resolved version
main PdfLoader regression: text extraction and page/structure mapping (test/fixtures/sample.pdf, plus the existing parser tests)
Packaged artifact verified on Windows and macOS, not just dev — this dependency is externalized and ships in app.asar, so a dev-only check proves nothing about the shipped build
npm audit --omit=dev clean against pdfjs-dist (note: needs --registry=https://registry.npmjs.org; the configured mirror has no audit endpoint)
Rollback plan recorded: what breaks if 6.x is rejected, and how the app behaves on the previous version
Prefer not to ship at all
Even if enableScripting: false demonstrably blocks the current exploit path, the intent is that
v1.4 does not ship a version inside a known-high affected range. Untrusted PDFs are the normal
input model for this app, not an edge case, so a known-high in that path should not be deferred to
a later release.
If the 6.x upgrade turns out to be large, this becomes a decision point rather than an automatic
deferral — bring the comparison back here, do not silently push it to v1.5.
isEvalSupported (font-data eval) is a different vector, not this CVE. Worth confirming
during the upgrade, but not a reason to treat this issue as bigger than it is.
Background
Found while running the dependency audit for #62 (pdfjs-dist is one of the three dependencies in
its scope). Audit command and result:
$ npm audit --omit=dev --registry=https://registry.npmjs.org
# npm audit report
pdfjs-dist >=5.6.83 <6.2.108
Severity: high
PDF.js: Arbitrary JavaScript execution upon opening a malicious PDF
1 high severity vulnerability
Status
Addressed by #124. The current exploit path is not reachable under the inspected call sites — that is a statement about our code (no AnnotationLayer, no viewer import, and PDFScriptingManager absent from the API build), not a claim that the library is safe, and it is now guarded by a test rather than assumed. The renderer additionally already sets script-src 'self' with no 'unsafe-inline'/'unsafe-eval', so the advisory's "no CSP" prerequisite is not met either.
Upgraded to 6.3.289; the only API breakage was destroy() moving from PDFDocumentProxy to PDFDocumentLoadingTask (three call sites). npm audit --omit=dev now reports 0 vulnerabilities. Reader rendering regression remains manual QA.
v1.4 release blocker
pdfjs-distis pinned independenciesand is the parsing engine for the app's core input, so aknown-high advisory cannot ship in v1.4. The library is affected; the reachability of the exploit
in KnowNote is a separate question, and the evidence below says it is not currently reachable —
which is why this is a scheduled, deliberate upgrade rather than a fire. It is still a blocker,
because "not reachable" here rests on our own call sites rather than on anything the library
guarantees.
Advisory
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:N/SC:N/SI:N/SA:Npdfjs-dist >=5.6.83 <6.2.1086.2.1085.7.284— inside the affected range (package.jsondeclares^5.4.530; the lockfile resolves to 5.7.284)Advisory impact statement, verbatim:
Official workarounds: "Set
enableScriptingtofalseor set a CSP."Exploit conditions in KnowNote — checked, not assumed
Both PDF paths were inspected. Neither opts into the vulnerable path, and neither instantiates the
component that would exercise it:
src/main/services/loaders/PdfLoader.ts:68getDocument({ data, password })— noenableScriptinggetMetadata(),page.getTextContent()src/renderer/src/components/notebook/source/reader/PdfSourceReader.tsx:211getDocument({ data })— no optionspage.render()(canvas) +pdfjs.TextLayerThe advisory's prerequisite is
enableScripting: trueplus the code that acts on it:enableScriptingis consumed byAnnotationLayer(annotation JS actions) and by the viewer'sPDFScriptingManager, which is what actually executes document JavaScript.AnnotationLayerand imports nopdfjs-dist/web/*. In the installedpackage,
PDFScriptingManagerappears only inweb/pdf_viewer.mjs—grep -c PDFScriptingManageragainst the API build
build/pdf.mjsis 0.pdfjs-distresolves tomain: build/pdf.mjs, i.e. the API build, for the renderer; themain process imports
pdfjs-dist/legacy/build/pdf.mjs. The only other import is the parsingworker (
build/pdf.worker.min.mjs?url).eval()/new Function()scripting primitive: the annotation layer's_bindJSActiononly binds DOM listeners that dispatch into a sandbox the viewer is expected toprovide.
Conclusion: the stated exploit conditions are not met on either path today. This must be
re-verified as part of this issue, because the conclusion depends on our call sites: adding an
annotation layer, or the
#71renderer-side PDF spike, would put the vulnerable code back in scope.Acceptance
PdfLoader, rendererPdfSourceReader) and the finding recorded, so the reasoning survives the next reader— corrected, this was not implementable.enableScripting: falsepassed explicitly on bothgetDocumentcallsenableScriptingis declared onAnnotationLayer/AnnotationLayerBuilder/PDFViewer, and is not aDocumentInitParametersmember, so TypeScript rejects it ongetDocument(TS2353). The advisory's workaround targets the viewer, which this app does not use, so there is no switch to flip at our call sites.The mitigation is therefore structural, and is now a CI-enforced invariant rather than a one-time inspection:
test/pdfjsScriptingBoundary.test.tsfails if anything imports the viewer build (wherePDFScriptingManagerlives), constructs the annotation layer or scripting manager, or setsenableScripting: true— with a self-check so it cannot pass by scanning nothing.pdfjs-dist >=6.2.108; confirm6.xis the first fixed line and record the resolved versionbbox, worker loading, zoomPdfLoaderregression: text extraction and page/structure mapping (test/fixtures/sample.pdf, plus the existing parser tests)externalizedand ships inapp.asar, so a dev-only check proves nothing about the shipped buildnpm audit --omit=devclean againstpdfjs-dist(note: needs--registry=https://registry.npmjs.org; the configured mirror has no audit endpoint)6.xis rejected, and how the app behaves on the previous versionPrefer not to ship at all
Even if
enableScripting: falsedemonstrably blocks the current exploit path, the intent is thatv1.4 does not ship a version inside a known-high affected range. Untrusted PDFs are the normal
input model for this app, not an edge case, so a known-high in that path should not be deferred to
a later release.
If the
6.xupgrade turns out to be large, this becomes a decision point rather than an automaticdeferral — bring the comparison back here, do not silently push it to v1.5.
Explicitly not in scope
app.asar245 MB +app.asar.unpacked218 MB).That is real, and it is evidence for the
@huggingface/transformers/onnxruntime-nodequestion in [Chore] Audit the three dependencies that gate provenance and retrieval #62 — it is not part of this issue.
widen the blast radius of this advisory.
isEvalSupported(font-dataeval) is a different vector, not this CVE. Worth confirmingduring the upgrade, but not a reason to treat this issue as bigger than it is.
Background
Found while running the dependency audit for #62 (
pdfjs-distis one of the three dependencies inits scope). Audit command and result:
Status
Addressed by #124. The current exploit path is not reachable under the inspected call sites — that is a statement about our code (no
AnnotationLayer, no viewer import, andPDFScriptingManagerabsent from the API build), not a claim that the library is safe, and it is now guarded by a test rather than assumed. The renderer additionally already setsscript-src 'self'with no'unsafe-inline'/'unsafe-eval', so the advisory's "no CSP" prerequisite is not met either.Upgraded to 6.3.289; the only API breakage was
destroy()moving fromPDFDocumentProxytoPDFDocumentLoadingTask(three call sites).npm audit --omit=devnow reports 0 vulnerabilities. Reader rendering regression remains manual QA.