CVE-2026-118256

CVE-2026-118256 is a low-severity cross-site scripting (XSS) vulnerability in vue-i18n (npm), affecting versions >= 9.0.0-beta.5, < 11.4.14. It is fixed in 11.4.14, 12.0.0-alpha.5.

Does this CVE actually affect you?

Kodem shows which CVEs are reachable and running in your applications, so you fix what's exploitable, not just what's listed.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Runtime intelligence, not another scanner.

Summary

Vue I18n: escapeParameter does not escape named values when the same call also passes a list

When escapeParameter is enabled (escapeParameterHtml in the Legacy API), Vue I18n escapes the interpolation parameters before formatting a message. escapeParams() escapes either the list values or the named values, but not both: the two branches are joined by else. When a single call passes both, for example t(key, ['...'], { named: { ... } }), the named values reach the message without being escaped.

Details

escapeParams() in packages/core-base/src/translate.ts (v11.4.13):

function escapeParams(options: TranslateOptions) {
  if (isArray(options.list)) {
    options.list = options.list.map(item => (isString(item) ? escapeHtml(item) : item))
  } else if (isObject(options.named)) {
    // ...escapes the named values
  }
}

t(key, list, options) is a public overload, and TranslateOptions has a named field, so a call can carry both. The list is checked first, and the named values are then left as they are.

The translated string still goes through sanitizeTranslatedHtml() (added for CVE-2025-53892), which neutralizes event handler attributes and javascript: URLs. Other markup in the named values, such as links and forms, is inserted as is. Before the fix for GHSA-83rm-6c8r-g728, an <iframe srcdoc> in a named value also passes the sanitizer, and script runs. Versions without the sanitizer (before 9.14.5, 10.0.8 and 11.1.10, and 12.0.0-alpha.1 to alpha.3) insert the named values as HTML without any further check.

<i18n-t> is not affected: it passes either list or named values, never both, and it does not render translations as HTML.

PoC

import { createI18n } from 'vue-i18n'

const i18n = createI18n({
  legacy: false,
  locale: 'en',
  escapeParameter: true,
  messages: {
    en: { withList: '{0} {name}', withoutList: '{name}' }
  }
})
const t = i18n.global.t

t('withoutList', { name: '<b>x</b>' })
// &lt;b&gt;x&lt;&#x2F;b&gt;      escaped

t('withList', ['a'], { named: { name: '<b>x</b>' } })
// a <b>x</b>                   not escaped (v11.4.13)

Workarounds

  • Do not pass list and named values in the same call when escapeParameter is enabled.
  • Do not render translations that can contain untrusted values with v-html. Use component interpolation (<i18n-t>) instead.

Impact

Applications are affected when they enable escapeParameter, render translations as HTML (for example with v-html), and pass untrusted named values in the same call as a list. The named values are inserted as markup: phishing links, forms, or layout changes. Together with GHSA-83rm-6c8r-g728, or on versions without the sanitizer, this leads to script execution (DOM-based XSS).

Untrusted input is rendered as active markup in a victim's browser, which can run script in their session. Typical impact: session or credential theft, and actions taken as the user.

Affected versions

vue-i18n (>= 9.0.0-beta.5, < 11.4.14) vue-i18n (>= 12.0.0-alpha.1, < 12.0.0-alpha.5) @intlify/core (>= 9.0.0-beta.10, < 11.4.14) @intlify/core (>= 12.0.0-alpha.1, < 12.0.0-alpha.5) @intlify/core-base (>= 9.0.0-beta.12, < 11.4.14) @intlify/core-base (>= 12.0.0-alpha.1, < 12.0.0-alpha.5) petite-vue-i18n (>= 9.2.0-alpha.7, < 11.4.14) petite-vue-i18n (>= 12.0.0-alpha.1, < 12.0.0-alpha.5) @intlify/vue-i18n-core (>= 9.2.0-alpha.7, < 11.4.14) @intlify/vue-i18n-core (>= 12.0.0-alpha.1, < 12.0.0-alpha.5)

Security releases

vue-i18n → 11.4.14 (npm) vue-i18n → 12.0.0-alpha.5 (npm) @intlify/core → 11.4.14 (npm) @intlify/core → 12.0.0-alpha.5 (npm) @intlify/core-base → 11.4.14 (npm) @intlify/core-base → 12.0.0-alpha.5 (npm) petite-vue-i18n → 11.4.14 (npm) petite-vue-i18n → 12.0.0-alpha.5 (npm) @intlify/vue-i18n-core → 11.4.14 (npm) @intlify/vue-i18n-core → 12.0.0-alpha.5 (npm)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

Already deployed Kodem?

See it in your environmentNew to Kodem? Get a demo →

Remediation advice

Fixed in 11.4.14 and 12.0.0-alpha.5. escapeParams() now escapes both the list and the named values.

The fix also stops rewriting the named object that the caller passes. Before, the values of that object were replaced with their escaped form, so a second call with the same object escaped them twice.

v9 and v10 are no longer supported and will not be fixed. Please migrate to v11.

Frequently Asked Questions

  1. What is CVE-2026-118256? CVE-2026-118256 is a low-severity cross-site scripting (XSS) vulnerability in vue-i18n (npm), affecting versions >= 9.0.0-beta.5, < 11.4.14. It is fixed in 11.4.14, 12.0.0-alpha.5. Untrusted input is rendered as active markup in a victim's browser, which can run script in their session.
  2. Which packages are affected by CVE-2026-118256?
    • vue-i18n (npm) (versions >= 9.0.0-beta.5, < 11.4.14)
    • @intlify/core (npm) (versions >= 9.0.0-beta.10, < 11.4.14)
    • @intlify/core-base (npm) (versions >= 9.0.0-beta.12, < 11.4.14)
    • petite-vue-i18n (npm) (versions >= 9.2.0-alpha.7, < 11.4.14)
    • @intlify/vue-i18n-core (npm) (versions >= 9.2.0-alpha.7, < 11.4.14)
  3. Is there a fix for CVE-2026-118256? Yes. CVE-2026-118256 is fixed in 11.4.14, 12.0.0-alpha.5. Upgrade to this version or later.
  4. Is CVE-2026-118256 exploitable, and should I be worried? Whether CVE-2026-118256 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  5. What actually determines whether CVE-2026-118256 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  6. How do I fix CVE-2026-118256?
    • Upgrade vue-i18n to 11.4.14 or later
    • Upgrade vue-i18n to 12.0.0-alpha.5 or later
    • Upgrade @intlify/core to 11.4.14 or later
    • Upgrade @intlify/core to 12.0.0-alpha.5 or later
    • Upgrade @intlify/core-base to 11.4.14 or later
    • Upgrade @intlify/core-base to 12.0.0-alpha.5 or later
    • Upgrade petite-vue-i18n to 11.4.14 or later
    • Upgrade petite-vue-i18n to 12.0.0-alpha.5 or later
    • Upgrade @intlify/vue-i18n-core to 11.4.14 or later
    • Upgrade @intlify/vue-i18n-core to 12.0.0-alpha.5 or later

Other vulnerabilities in vue-i18n

Stop the waste.
Protect your environment with Kodem.