fix: load file-type via ESM-safe shim to allow bump to ^21 (CVE-2026-31808)#127
Open
hhorton-onebrief wants to merge 1 commit into
Open
fix: load file-type via ESM-safe shim to allow bump to ^21 (CVE-2026-31808)#127hhorton-onebrief wants to merge 1 commit into
hhorton-onebrief wants to merge 1 commit into
Conversation
…31808) file-type@17+ is ESM-only. docu-notion's commonjs build rewrites `import` and `await import()` into `require()`, which crashes on ESM-only packages. This blocked security upgrades past file-type@16.5.3. Downstream consumers who apply a security resolution pinning `file-type` to ^21.x currently crash in src/images.ts because `FileType.fromBuffer` no longer exists on the v21 API. This change adds src/fileType.ts, a thin wrapper that uses `new Function("return import('file-type')")` to hide the dynamic import from TypeScript's commonjs transform. src/images.ts is rewired to use the shim. Node 20+ is now required (file-type@21 engines constraint).
|
|
Author
|
fixes: #128 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes CVE-2026-31808 (file-type DoS via crafted ASF header, CVSS 5.3) by upgrading
file-typefrom16.5.3to^21.0.0.The existing
"//file-type"comment inpackage.jsondocuments why this bump was previously blocked:file-type@17+is ESM-only, and a staticimport from "file-type"undertsconfig module: commonjsgets rewritten torequire("file-type"), which fails on ESM-only packages. Downstream consumers who add a resolution forcingfile-typeto the CVE-fixed21.3.3currently hit a runtime crash insrc/images.tsbecauseFileType.fromBufferno longer exists on the v21 API.This PR resolves the CJS↔ESM boundary without changing the project's compile target.
Approach
Added
src/fileType.ts, a 24-line shim that wrapsfile-type's ESM API behind anew Function("return import('file-type')")trampoline. TypeScript'scommonjstransform does not inspect strings insidenew Function(...), so theimport()expression reaches Node's native dynamic import at runtime.src/images.tsis rewired to calldetectFileType(buffer)from the shim instead of the old staticFileType.fromBuffer.The shim is quarantined to a single file with a comment explaining the rationale. If the project later migrates to ESM, the shim becomes a one-file delete plus inlining a static import in
src/images.ts.Changes
package.jsonfile-typefrom16.5.3to^21.0.0."//file-type"workaround comment (workaround is now documented at its point of use)."engines": { "node": ">=20" }—file-type@21requires Node 20+, so the project's floor shifts. Matches the existingvolta.nodepin.src/fileType.ts(new, 24 lines) — typeddetectFileType(buffer)helper and localFileTypeResult = { ext: string; mime: string }type.src/images.ts— two-line diff: replace the staticfile-typeimport with one from./fileType, and replace theFileType.fromBuffer(...)call withdetectFileType(...).ImageSet.fileType?: FileTypeResultis unchanged (identifier resolves to the local re-export, same shape).Breaking change
Minimum Node version moves from
14+(implicit, viafile-type@16) to20+(required byfile-type@21). The"engines"field makes this a loudEBADENGINEwarning at install time rather than a silent runtime crash.Test plan
npm run buildpasses (vitest + tsc).dist/*.jscontains norequire("file-type")— the only reference is thenew Functionstring literal indist/fileType.js.npm run pull-test-taggedcompletes successfully against a live Notion workspace. Downloaded images land with correct buffer-detected extensions (noERR_REQUIRE_ESM, nofromBuffer is not a function).Notes for reviewers
^21.0.0rather than^22.0.0, since file-type@22 raises the Node floor to 22.^21.0.0satisfies the CVE fix (shipped in 21.3.3), accepts forward patch updates in the 21.x line, and keeps Node 20 in the compatibility matrix.new Functionrather thanawait import("file-type")directly: undertsc --module commonjs,await import("file-type")compiles toPromise.resolve().then(() => require("file-type")), which crashes on ESM-only modules. Thenew Functionescape hatch is the standard, widely-used CJS→ESM bridge (see also:tsimportlib,dynamic-import-function). Inlined here to avoid adding a tiny runtime dep.This change is