Skip to main content

Boteraser | Website and Server Security Solutions

🛡️ GHSA-r27j-894h-3w3p — icu-minify

🟢 CVSS 2.0 — Low ✅ No Known Exploit CWE-1321 OSV
2.0
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

mcp-data-vis vulnerable to denial of service via unsanitized select key lookup on Object.prototype with precompile: true

Summary

icu-minify's runtime formatter resolves select branches by looking up the runtime value as a plain property on a prototype-bearing object. When the value coerces to a key that exists on Object.prototype (e.g. toString, __proto__, constructor, hasOwnProperty, valueOf), the lookup returns a truthy value that short-circuits the ?? options.other fallback, and the downstream iterator crashes with TypeError: nodes is not iterable. Any consumer that forwards user input into a {arg, select, …} placeholder — a common idiom for role, status, type, gender — can be crashed per-request by supplying one of those keys. In Next.js SSR (via next-intl with experimental.messages.precompile) this yields a 500 for the affected render.

Details

Vulnerable code paths

Compilation produces a plain object whose prototype chain includes all Object.prototype members:

```tsx

// packages/icu-minify/src/compile.tsx:191-199

function compileSelect(node: SelectElement): CompiledNode {

const options: SelectOptions = {}; // <-- plain object, inherits from Object.prototype

for (const [key, option] of Object.entries(node.options)) {

options[key] = compileNodesToNode(option.value);

}

return [node.value, TYPE_SELECT, options];

}

```

At runtime, the formatter looks up the user-controllable value directly on that object:

```tsx

// packages/icu-minify/src/format.tsx:226-244

function formatSelect<RichTextElement>(

name: string,

options: SelectOptions,

locale: string,

values: FormatValues<RichTextElement>,

formatOptions: FormatOptions,

pluralCtx: PluralContext | undefined

): string | RichTextElement | Array<string | RichTextElement> {

const value = String(getValue(values, name)); // 234: coerce to string, no sanitization

const branch: CompiledNode | undefined = options[value] ?? options.other; // 235: unsafe lookup

if (process.env.NODE_ENV !== 'production' && !branch) {

throw new Error(

No matching branch for select "${name}" with value "${value}"

);

}

return formatBranch(branch, locale, values, formatOptions, pluralCtx); // 243

}

```

Because options inherits from Object.prototype, lookups such as options['toString'] return Object.prototype.toString — a truthy Function. The ?? options.other fallback is therefore skipped, and the non-array, non-string branch is passed to formatBranch, which forwards it to formatNodes:

```tsx

// packages/icu-minify/src/format.tsx:286-308

function formatBranch<RichTextElement>(

branch: CompiledNode,

/* … */

) {

if (typeof branch === 'string') return branch; // string: fine

if (branch === TYPE_POUND) return formatNode(/* … */); // pound: fine

return formatNodes(branch as Array<CompiledNode>, /* … */); // 301: Function is not iterable

}

// packages/icu-minify/src/format.tsx:73-92

function formatNodes<RichTextElement>(

nodes: Array<CompiledNode>,

/* … */

): Array<string | RichTextElement> {

const result: Array<string | RichTextElement> = [];

for (const node of nodes) { // 82: TypeError: nodes is not iterable

/* … */

}

return result;

}

```

Five bare-prototype keys reliably crash the formatter in production: toString, __proto__, constructor, hasOwnProperty, valueOf (plus propertyIsEnumerable, isPrototypeOf, toLocaleString). Note the development branch at line 237 (throw new Error('No matching branch for select …')) is bypassed because the inherited function is truthy — so this is not masked in development either.

Why formatPlural is not affected

formatPlural (format.tsx:246-284) looks safe for two independent reasons and does not need to be patched for this specific bug:

1. Exact-match keys use the =${value} prefix (exactKey = '=' + value, line 263), so the attacker would need to supply e.g. =toString, which is not a member of Object.prototype.

2. The category branch uses formatOptions.formatters.getPluralRules(locale, {type}).select(value) which returns a fixed enum (zero|one|two|few|many|other), never attacker-supplied.

The bug is specific to the select path where the raw string value is used as the lookup key.

Reachability

  • Direct consumers of icu-minify: any code calling format(compiled, locale, values, …) where values[arg] for a select placeholder comes from user input is vulnerable with no additional preconditions.
  • next-intl users who enable experimental.messages.precompile (packages/next-intl/src/plugin/types.tsx:24, wired in packages/next-intl/src/plugin/getNextConfig.tsx:177-293): the runtime at packages/use-intl/src/core/format-message/format-only.tsx forwards directly to icu-minify/format, so t('msg', {role: req.query.role}) against a {role, select, admin {…} other {…}} message crash

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is high, an attacker needs no privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality none, integrity none, availability low.

Weakness class

GHSA-r27j-894h-3w3p is classified as CWE-1321: Prototype Pollution. Attacker input can modify an object prototype, changing behaviour for objects across the application.

Affected software

GHSA-r27j-894h-3w3p is recorded against 1 package.

  • icu-minify

Timeline and source

Published on 6 May 2026. No public exploit is currently recorded for this entry. Record sourced from OSV.

References

github.com (Web)
github.com (Package)

Details

Severity LOW
CVSS Score 2.0
CVSS Vector CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
CWE CWE-1321
Public Exploit ✅ No
Source OSV
Published 2026-05-06
Updated 2026-08-20
Modified 2026-05-06
Fix URL N/A

Affected Packages

Software From version Fixed in
icu-minify

Free Vulnerability Check

Is your site affected by GHSA-r27j-894h-3w3p?

BotEraser helps you identify potentially vulnerable plugins and themes by checking your installation against GHSA-r27j-894h-3w3p and other known CVE records.

Scan My Site Free →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.