Repository navigation
Description
Four Dependabot alerts on image-size (#1415, #1416, #1342, #1343) are being dismissed as tolerable_risk rather than fixed. This issue records why, so the decision is auditable and gets revisited rather than quietly forgotten.
| Alert | Advisory | Severity | Manifest |
|---|---|---|---|
| #1416 | GHSA-w3rx-r6r6-pgpr — ICNS parser infinite loop | High | website/yarn.lock |
| #1415 | GHSA-5p2g-fcmc-qvqq — JXL/HEIF parser infinite loops | High | website/yarn.lock |
| #1343 | GHSA-w3rx-r6r6-pgpr | High | website/src/plugins/docusaurus-plugin-content-docs-extend/yarn.lock |
| #1342 | GHSA-5p2g-fcmc-qvqq | High | same plugin lockfile |
1. There is no version to upgrade to
Both advisories declare the vulnerable range as <= 2.0.2 with first_patched_version: null. Checking the registry directly: image-size has 71 published versions, dist-tags.latest is 2.0.2, published 2025-04-02, and nothing above 2.0.2 exists — not even a prerelease.
So the advisory range covers every version that has ever shipped. A bump, a resolutions entry and an override are all equally useless here; this is not a case of us being behind.
2. It only runs at build time, and is not in what we deploy
image-size reaches us through exactly one path: @docusaurus/mdx-loader@3.10.2. Its transformImage remark plugin calls it while compiling markdown:
// @docusaurus/mdx-loader/lib/remark/transformImage/index.js:69
const size = (await imageSizeFromFile(imagePath));imagePath is resolved from an image reference in our own docs and read off local disk. That happens once, in CI, while building the docs. The deployed artifact is static HTML — image-size is not part of any bundle a visitor loads, and it never executes in response to a request. Nothing an external party controls reaches it.
3. The two vulnerable parsers are never entered
This is the part that actually bounds the risk, so it is worth being precise. image-size picks a decoder by magic bytes, not by file extension:
// image-size@2.0.2 dist/detector.mjs:953-960
function detector(input) {
const byte = input[0];
const type = firstBytes.get(byte);
if (type && typeHandlers.get(type).validate(input)) return type;
return types.find((t) => typeHandlers.get(t).validate(input));
}The ICNS handler's guard is toUTF8String(input, 0, 4) === "icns" — the file must literally begin with those four bytes. HEIF and JXL have their own signatures. A JPEG (0xFF) or PNG (0x89) can never be routed into them.
And there is no such file to route. Across the entire repository there are zero .icns, .jxl, .heif and .heic files. Everything under website/ is 26 .jpg, 12 .png, 8 .svg, 6 .jpeg, 2 .ico.
Residual risk
Both advisories are denial of service via an infinite loop — not memory corruption, not code execution. Combining that with the two points above, the realistic worst case if someone committed a malicious ICNS file to this repo is that a CI docs build hangs. That is visible, contained, and reverted by dropping the commit. It is not a production exposure.
Dismissing is therefore more honest than leaving four permanently-unfixable High alerts open, where they add noise to every future security review and make it harder to notice a real one.
When to revisit
Reopen and fix if any of the following becomes true:
- upstream publishes an
image-sizerelease above 2.0.2 that carries the fix, or - Docusaurus moves
mdx-loaderoffimage-size, or - we start committing ICNS, JXL, HEIF or HEIC assets, or begin processing images from an untrusted source at build time.
The first two are the likely exits and simply need a dependency bump once available.
Related
Cleared in the current sweep via #1058 and #1060 (75 → 23 alerts). The 23 that remain are react-scripts/CRA ×14 (needs a Vite migration) and Vue 2 in tools/azure-socketio-admin-ui ×5 (needs a Vue 3 migration), plus these 4.
Activity