VYPR
High severity8.6NVD Advisory· Published May 8, 2026· Updated May 12, 2026

CVE-2026-41683

CVE-2026-41683

Description

i18next-http-middleware is a middleware to be used with Node.js web frameworks like express or Fastify and also for Deno. Prior to version 3.9.3, i18next-http-middleware wrote user-controlled language values into the Content-Language response header after passing them through utils.escape(), which is an HTML-entity encoder that does not strip carriage return, line feed, or other control characters. When the application used an older i18next (< 19.5.0) that still exercised the backward-compatibility fallback at LanguageDetector.js:100 or otherwise produced a raw detected value, CRLF sequences in the attacker-controlled lng parameter reached res.setHeader('Content-Language', ...) verbatim. This issue has been patched in version 3.9.3.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
i18next-http-middlewarenpm
< 3.9.33.9.3

Affected products

1

Patches

1
65301c194593

security: harden setPath, CRLF, missingKeyHandler, getResourcesHandler, hasXSS, cookie SameSite

https://github.com/i18next/i18next-http-middlewareAdriano RaianoApr 18, 2026via ghsa
16 files changed · +287 48
  • CHANGELOG.md+10 0 modified
    @@ -1,3 +1,13 @@
    +## [v3.9.3](https://github.com/i18next/i18next-http-middleware/compare/v3.9.2...v3.9.3)
    +Security release — all issues found via an internal audit. GHSA advisories filed after release.
    +- security: guard `utils.setPath` against prototype pollution via crafted `lng`/`ns` in `getResourcesHandler` (GHSA-TBD)
    +- security: sanitise `Content-Language` response header to prevent CRLF injection / unhandled `ERR_INVALID_CHAR` crash via unsanitised language codes (GHSA-TBD)
    +- security: skip inherited/prototype-polluting keys (`__proto__`, `constructor`, `prototype`) in `missingKeyHandler` request body
    +- security: filter unsafe `lng`/`ns` values in `getResourcesHandler` (reject path-traversal, path separators, control characters, prototype keys, over-long inputs) to prevent path traversal / SSRF via the backend connector and unbounded growth of the shared `i18next.options.ns` array. Any legitimate language code shape is still accepted — i18next permits arbitrary codes ([FAQ](https://www.i18next.com/how-to/faq#how-should-the-language-codes-be-formatted))
    +- security: `hasXSS` regex now catches event handlers in any attribute position (previously only matched when the handler was the first attribute; e.g. `<input autofocus onfocus=…>` bypassed the filter)
    +- security: automatically set the `Secure` flag on the language cookie when `cookieSameSite: 'none'` — browsers reject `SameSite=None` without `Secure`
    +- chore: ignore `.env*` and `*.pem`/`*.key` files in `.gitignore`
    +
     ## [v3.9.2](https://github.com/i18next/i18next-http-middleware/compare/v3.9.1...v3.9.2)
     - TS definition for default export [#100](https://github.com/i18next/i18next-http-middleware/issues/100)
     
    
  • .github/workflows/deno.yml+2 2 modified
    @@ -20,9 +20,9 @@ jobs:
             # os: [ubuntu-latest, windows-latest, macOS-latest]
             os: [ubuntu-latest]
         steps:
    -      - uses: actions/checkout@v2
    +      - uses: actions/checkout@v6
           - name: Setup Deno
    -        uses: denolib/setup-deno@master
    +        uses: denoland/setup-deno@v2
             with:
               deno-version: ${{ matrix.deno }}
           - run: deno --version
    
  • .github/workflows/node.yml+3 3 modified
    @@ -16,13 +16,13 @@ jobs:
         runs-on: ${{ matrix.os }}
         strategy:
           matrix:
    -        node: [ '22.x', '20.x', '18.x' ]
    +        node: [ '24.x', '22.x', '20.x' ]
             # os: [ubuntu-latest, windows-latest, macOS-latest]
             os: [ubuntu-latest]
         steps:
    -      - uses: actions/checkout@v3
    +      - uses: actions/checkout@v6
           - name: Setup Node.js
    -        uses: actions/setup-node@v3
    +        uses: actions/setup-node@v6
             with:
               node-version: ${{ matrix.node }}
           - run: npm install
    
  • .gitignore+5 0 modified
    @@ -4,3 +4,8 @@ package-lock.json
     yarn.lock
     cjs
     esm
    +.env
    +.env.*
    +!.env.example
    +*.pem
    +*.key
    
  • lib/index.js+21 8 modified
    @@ -69,7 +69,7 @@ export function handle (i18next, options = {}) {
           }
     
           if (lng && options.getHeader(res, 'Content-Language') !== lng) {
    -        options.setHeader(res, 'Content-Language', utils.escape(lng))
    +        options.setHeader(res, 'Content-Language', utils.sanitizeHeaderValue(lng))
           }
     
           req.languages = i18next.services.languageUtils.toResolveHierarchy(lng)
    @@ -88,7 +88,7 @@ export function handle (i18next, options = {}) {
         // set locale
         req.language = req.locale = req.lng = lng
         if (lng && options.getHeader(res, 'Content-Language') !== lng) {
    -      options.setHeader(res, 'Content-Language', utils.escape(lng))
    +      options.setHeader(res, 'Content-Language', utils.sanitizeHeaderValue(lng))
         }
         req.languages = i18next.services.languageUtils.toResolveHierarchy(lng)
         req.resolvedLanguage = i18n.resolvedLanguage
    @@ -243,6 +243,14 @@ export function getResourcesHandler (i18next, options = {}) {
             : []
         }
     
    +    // Drop user-supplied values containing patterns that could trigger path
    +    // traversal / SSRF / prototype pollution when forwarded to the backend
    +    // connector. i18next itself permits arbitrary language codes, so we do
    +    // not impose a BCP-47 shape — we only block known-dangerous patterns.
    +    // See: https://www.i18next.com/how-to/faq#how-should-the-language-codes-be-formatted
    +    languages = languages.filter(utils.isSafeIdentifier)
    +    namespaces = namespaces.filter(utils.isSafeIdentifier)
    +
         // extend ns
         namespaces.forEach(ns => {
           if (i18next.options.ns && i18next.options.ns.indexOf(ns) < 0) {
    @@ -290,23 +298,28 @@ export function missingKeyHandler (i18next, options = {}) {
     
         const body = options.getBody(req)
     
    +    // iterate only over own, non-prototype-polluting keys
    +    const saveMissingKeys = src => {
    +      if (!src || typeof src !== 'object') return
    +      for (const m of Object.keys(src)) {
    +        if (utils.UNSAFE_KEYS.indexOf(m) > -1) continue
    +        i18next.services.backendConnector.saveMissing([lng], ns, m, src[m])
    +      }
    +    }
    +
         if (typeof body === 'function') {
           const promise = body()
           if (promise && typeof promise.then === 'function') {
             return new Promise(resolve => {
               promise.then(b => {
    -            for (const m in b) {
    -              i18next.services.backendConnector.saveMissing([lng], ns, m, b[m])
    -            }
    +            saveMissingKeys(b)
                 resolve(options.send(res, 'ok'))
               })
             })
           }
         }
     
    -    for (const m in body) {
    -      i18next.services.backendConnector.saveMissing([lng], ns, m, body[m])
    -    }
    +    saveMissingKeys(body)
     
         return options.send(res, 'ok')
       }
    
  • lib/languageLookups/cookie.js+7 0 modified
    @@ -86,6 +86,13 @@ export default {
     
           if (options.cookieSecure) cookieOptions.secure = options.cookieSecure
     
    +      // SameSite=None requires Secure — browsers reject the cookie otherwise.
    +      // Force Secure in that case so misconfigured setups still function.
    +      const sameSiteNormalised = typeof cookieOptions.sameSite === 'string'
    +        ? cookieOptions.sameSite.toLowerCase()
    +        : cookieOptions.sameSite
    +      if (sameSiteNormalised === 'none') cookieOptions.secure = true
    +
           let existingCookie = options.getHeader(res, 'set-cookie') || options.getHeader(res, 'Set-Cookie') || []
           if (typeof existingCookie === 'string') existingCookie = [existingCookie]
           if (!Array.isArray(existingCookie)) existingCookie = []
    
  • lib/utils.js+35 2 modified
    @@ -1,3 +1,25 @@
    +export const UNSAFE_KEYS = ['__proto__', 'constructor', 'prototype']
    +
    +// Returns true if `v` can be safely forwarded as a language code or namespace
    +// identifier to a backend connector. Denylist approach (i18next permits any
    +// language-code shape — https://www.i18next.com/how-to/faq#how-should-the-language-codes-be-formatted)
    +// that blocks the concrete attack patterns without restricting legitimate use:
    +//   - not one of `__proto__` / `constructor` / `prototype` (prototype pollution)
    +//   - no path separators `/` or `\` (path traversal / SSRF in fs/http backends)
    +//   - no `..` sequence (relative path traversal)
    +//   - no control characters (header injection downstream, log forging)
    +//   - non-empty, length <= 128
    +export function isSafeIdentifier (v) {
    +  if (typeof v !== 'string') return false
    +  if (v.length === 0 || v.length > 128) return false
    +  if (UNSAFE_KEYS.indexOf(v) > -1) return false
    +  if (v.indexOf('..') > -1) return false
    +  if (v.indexOf('/') > -1 || v.indexOf('\\') > -1) return false
    +  // eslint-disable-next-line no-control-regex
    +  if (/[\x00-\x1F\x7F]/.test(v)) return false
    +  return true
    +}
    +
     export function setPath (object, path, newValue) {
       let stack
       if (typeof path !== 'string') stack = [].concat(path)
    @@ -6,12 +28,14 @@ export function setPath (object, path, newValue) {
       while (stack.length > 1) {
         let key = stack.shift()
         if (key.indexOf('###') > -1) key = key.replace(/###/g, '.')
    +    if (UNSAFE_KEYS.indexOf(key) > -1) return // guard against prototype pollution
         if (!object[key]) object[key] = {}
         object = object[key]
       }
     
       let key = stack.shift()
       if (key.indexOf('###') > -1) key = key.replace(/###/g, '.')
    +  if (UNSAFE_KEYS.indexOf(key) > -1) return // guard against prototype pollution
       object[key] = newValue
     }
     
    @@ -70,15 +94,24 @@ export function escape (str) {
         .replace(/`/g, '&#96;'))
     }
     
    +// Strip control characters (CR, LF, NUL, other C0/C1) from a value before
    +// writing it into an HTTP header. Prevents HTTP response splitting on older
    +// Node.js, and unhandled ERR_INVALID_CHAR crashes on newer Node.js.
    +export function sanitizeHeaderValue (str) {
    +  if (typeof str !== 'string') return str
    +  // eslint-disable-next-line no-control-regex
    +  return str.replace(/[\r\n\x00-\x1F\x7F]/g, '')
    +}
    +
     export function hasXSS (input) {
       if (typeof input !== 'string') return false
     
       // Common XSS attack patterns
       const xssPatterns = [
         /<\s*script.*?>/i,
         /<\s*\/\s*script\s*>/i,
    -    /<\s*img.*?on\w+\s*=/i,
    -    /<\s*\w+\s*on\w+\s*=.*?>/i,
    +    // event handlers on any tag position (not just first attribute)
    +    /<\s*\w+\s+[^>]*?\bon\w+\s*=/i,
         /javascript\s*:/i,
         /vbscript\s*:/i,
         /expression\s*\(/i,
    
  • licence+1 1 modified
    @@ -1,4 +1,4 @@
    -Copyright (c) 2025 i18next
    +Copyright (c) 2020-present i18next
     
     Permission is hereby granted, free of charge, to any person obtaining a copy
     of this software and associated documentation files (the "Software"), to deal
    
  • package.json+16 16 modified
    @@ -28,15 +28,15 @@
       },
       "module": "./esm/index.js",
       "devDependencies": {
    -    "@babel/cli": "7.25.9",
    -    "@babel/core": "7.26.0",
    -    "@babel/preset-env": "7.26.0",
    -    "@hapi/hapi": "^21.3.12",
    -    "@opentelemetry/api": "^1.9.0",
    -    "@preact/signals": "^2.2.1",
    -    "@types/express-serve-static-core": "^5.0.1",
    -    "@koa/router": "12.0.1",
    -    "koa": "2.16.1",
    +    "@babel/cli": "7.28.6",
    +    "@babel/core": "7.29.0",
    +    "@babel/preset-env": "7.29.2",
    +    "@hapi/hapi": "^21.4.8",
    +    "@opentelemetry/api": "^1.9.1",
    +    "@preact/signals": "^2.9.0",
    +    "@types/express-serve-static-core": "^5.1.1",
    +    "@koa/router": "15.4.0",
    +    "koa": "3.2.0",
         "babel-plugin-add-module-exports": "1.0.4",
         "eslint": "8.53.0",
         "eslint-config-standard": "17.1.0",
    @@ -46,14 +46,14 @@
         "eslint-plugin-require-path-exists": "1.1.9",
         "eslint-plugin-standard": "5.0.0",
         "expect.js": "0.3.1",
    -    "express": "4.21.1",
    +    "express": "5.2.1",
         "fastify": "5.8.5",
    -    "i18next": "25.5.2",
    -    "mocha": "10.8.2",
    -    "preact": "10.27.3",
    -    "preact-render-to-string": "6.6.3",
    -    "supertest": "7.0.0",
    -    "tsd": "0.31.2",
    +    "i18next": "26.0.5",
    +    "mocha": "11.7.5",
    +    "preact": "10.29.1",
    +    "preact-render-to-string": "6.6.7",
    +    "supertest": "7.2.2",
    +    "tsd": "0.33.0",
         "uglify-js": "3.19.3"
       },
       "description": "i18next-http-middleware is a middleware to be used with Node.js web frameworks like express or Fastify and also for Deno.",
    
  • README.md+0 1 modified
    @@ -2,7 +2,6 @@
     
     [![Actions](https://github.com/i18next/i18next-http-middleware/workflows/node/badge.svg)](https://github.com/i18next/i18next-http-middleware/actions?query=workflow%3Anode)
     [![Actions deno](https://github.com/i18next/i18next-http-middleware/workflows/deno/badge.svg)](https://github.com/i18next/i18next-http-middleware/actions?query=workflow%3Adeno)
    -[![Travis](https://img.shields.io/travis/i18next/i18next-http-middleware/master.svg?style=flat-square)](https://travis-ci.org/i18next/i18next-http-middleware)
     [![npm version](https://img.shields.io/npm/v/i18next-http-middleware.svg?style=flat-square)](https://www.npmjs.com/package/i18next-http-middleware)
     
     This is a middleware to be used with Node.js web frameworks like express or Fastify and also for Deno.
    
  • test/addRoute.koa.js+1 1 modified
    @@ -5,7 +5,7 @@ import Koa from 'koa'
     import Router from '@koa/router'
     import request from 'supertest'
     
    -const router = Router()
    +const router = new Router()
     i18next.init({
       fallbackLng: 'en',
       preload: ['en', 'de'],
    
  • test/getResourcesHandler.koa.js+1 1 modified
    @@ -5,7 +5,7 @@ import Koa from 'koa'
     import Router from '@koa/router'
     import request from 'supertest'
     
    -const router = Router()
    +const router = new Router()
     i18next.init({
       fallbackLng: 'en',
       preload: ['en', 'de'],
    
  • test/middleware.koa.js+1 1 modified
    @@ -5,7 +5,7 @@ import Koa from 'koa'
     import Router from '@koa/router'
     import request from 'supertest'
     
    -const router = Router()
    +const router = new Router()
     i18next.init({
       fallbackLng: 'en',
       preload: ['en', 'de'],
    
  • test/missingKeyHandler.koa.js+1 1 modified
    @@ -5,7 +5,7 @@ import Koa from 'koa'
     import Router from '@koa/router'
     import request from 'supertest'
     
    -const router = Router()
    +const router = new Router()
     i18next.init({
       fallbackLng: 'en',
       preload: ['en', 'de'],
    
  • test/security.js+183 0 added
    @@ -0,0 +1,183 @@
    +import expect from 'expect.js'
    +import i18next from 'i18next'
    +import * as utils from '../lib/utils.js'
    +import LanguageDetector from '../lib/LanguageDetector.js'
    +import { getResourcesHandler, missingKeyHandler } from '../lib/index.js'
    +
    +// Tests covering the security fixes shipped in 3.9.3.
    +// See CHANGELOG.md for the associated advisories.
    +
    +describe('security', () => {
    +  describe('utils.setPath', () => {
    +    it('drops writes targeting __proto__, constructor, prototype', () => {
    +      const target = {}
    +      utils.setPath(target, ['__proto__', 'polluted'], 'yes')
    +      utils.setPath(target, ['constructor', 'polluted'], 'yes')
    +      utils.setPath(target, ['prototype', 'polluted'], 'yes')
    +      expect(({}).polluted).to.be(undefined)
    +      expect(Object.prototype.polluted).to.be(undefined)
    +    })
    +
    +    it('still writes safe nested paths', () => {
    +      const target = {}
    +      utils.setPath(target, ['en', 'common'], { k: 'v' })
    +      expect(target.en.common.k).to.eql('v')
    +    })
    +  })
    +
    +  describe('utils.sanitizeHeaderValue', () => {
    +    it('strips CR, LF, NUL and other control characters', () => {
    +      expect(utils.sanitizeHeaderValue('en\r\nX-Injected: bad')).to.eql('enX-Injected: bad')
    +      expect(utils.sanitizeHeaderValue('en\u0000')).to.eql('en')
    +      expect(utils.sanitizeHeaderValue('de-DE')).to.eql('de-DE')
    +    })
    +
    +    it('passes non-string values through unchanged', () => {
    +      expect(utils.sanitizeHeaderValue(undefined)).to.be(undefined)
    +      expect(utils.sanitizeHeaderValue(null)).to.be(null)
    +    })
    +  })
    +
    +  describe('utils.hasXSS', () => {
    +    it('detects event handlers regardless of attribute position', () => {
    +      // regression: /<\s*\w+\s*on\w+\s*=.*?>/i missed these
    +      expect(utils.hasXSS('<input autofocus onfocus=alert(1)>')).to.be(true)
    +      expect(utils.hasXSS('<details open ontoggle=alert(1)>')).to.be(true)
    +      expect(utils.hasXSS('<body id=x onscroll=alert(1)>')).to.be(true)
    +    })
    +
    +    it('still rejects obvious script tags and javascript: URIs', () => {
    +      expect(utils.hasXSS('<script>alert(1)</script>')).to.be(true)
    +      expect(utils.hasXSS('javascript:alert(1)')).to.be(true)
    +    })
    +
    +    it('accepts normal language codes', () => {
    +      expect(utils.hasXSS('en')).to.be(false)
    +      expect(utils.hasXSS('de-DE')).to.be(false)
    +      expect(utils.hasXSS('zh-Hant')).to.be(false)
    +    })
    +  })
    +
    +  describe('missingKeyHandler', () => {
    +    it('ignores __proto__/constructor/prototype keys in the request body', () => {
    +      const saved = []
    +      const fakeI18next = {
    +        services: {
    +          backendConnector: {
    +            saveMissing (lngs, ns, key, value) { saved.push({ lngs, ns, key, value }) }
    +          }
    +        }
    +      }
    +      const handler = missingKeyHandler(fakeI18next, {
    +        getParams: () => ({ lng: 'en', ns: 'translation' }),
    +        getBody: () => ({ key1: 'value1', __proto__: { isAdmin: true }, constructor: 'x', key2: 'value2' }),
    +        send: (_res, msg) => msg,
    +        setStatus: () => {}
    +      })
    +      handler({}, {})
    +      const keys = saved.map(s => s.key)
    +      expect(keys).to.contain('key1')
    +      expect(keys).to.contain('key2')
    +      expect(keys).not.to.contain('__proto__')
    +      expect(keys).not.to.contain('constructor')
    +      expect(keys).not.to.contain('prototype')
    +      expect(({}).isAdmin).to.be(undefined)
    +    })
    +  })
    +
    +  describe('utils.isSafeIdentifier', () => {
    +    it('accepts arbitrary language codes (i18next permits any shape)', () => {
    +      expect(utils.isSafeIdentifier('en')).to.be(true)
    +      expect(utils.isSafeIdentifier('de-DE')).to.be(true)
    +      expect(utils.isSafeIdentifier('en_US')).to.be(true)
    +      expect(utils.isSafeIdentifier('zh-Hant-HK')).to.be(true)
    +      expect(utils.isSafeIdentifier('pirate-speak')).to.be(true)
    +      expect(utils.isSafeIdentifier('my-custom.ns')).to.be(true)
    +    })
    +
    +    it('rejects path-traversal and prototype-pollution payloads', () => {
    +      expect(utils.isSafeIdentifier('__proto__')).to.be(false)
    +      expect(utils.isSafeIdentifier('constructor')).to.be(false)
    +      expect(utils.isSafeIdentifier('prototype')).to.be(false)
    +      expect(utils.isSafeIdentifier('../etc/passwd')).to.be(false)
    +      expect(utils.isSafeIdentifier('..')).to.be(false)
    +      expect(utils.isSafeIdentifier('foo/bar')).to.be(false)
    +      expect(utils.isSafeIdentifier('foo\\bar')).to.be(false)
    +      expect(utils.isSafeIdentifier('en\r\nX-Injected: bad')).to.be(false)
    +      expect(utils.isSafeIdentifier('en\u0000')).to.be(false)
    +      expect(utils.isSafeIdentifier('')).to.be(false)
    +      expect(utils.isSafeIdentifier('a'.repeat(200))).to.be(false)
    +      expect(utils.isSafeIdentifier(null)).to.be(false)
    +      expect(utils.isSafeIdentifier({ toString: () => 'en' })).to.be(false)
    +    })
    +  })
    +
    +  describe('getResourcesHandler', () => {
    +    it('drops unsafe lng/ns values but accepts arbitrary safe ones', async () => {
    +      const i18n = i18next.createInstance()
    +      await i18n.init({
    +        fallbackLng: 'en',
    +        ns: ['translation'],
    +        resources: { en: { translation: { hi: 'hello' } } }
    +      })
    +
    +      const nsBefore = [...i18n.options.ns]
    +
    +      const loadCalls = []
    +      i18n.services.backendConnector.load = (lngs, nss, cb) => {
    +        loadCalls.push({ lngs: [...lngs], nss: [...nss] })
    +        cb()
    +      }
    +
    +      const handler = getResourcesHandler(i18n, {
    +        getQuery: () => ({
    +          lng: '__proto__ ../etc/passwd en pirate-speak',
    +          ns: '__proto__ ../secrets translation custom.ns'
    +        }),
    +        getParams: () => ({}),
    +        setContentType: () => {},
    +        setHeader: () => {},
    +        getHeader: () => undefined,
    +        send: () => 'sent'
    +      })
    +      handler({}, {})
    +
    +      await new Promise(resolve => setTimeout(resolve, 10))
    +
    +      expect(loadCalls).to.have.length(1)
    +      // attack payloads dropped; legitimate values (including non-BCP-47 ones) kept
    +      expect(loadCalls[0].lngs).to.eql(['en', 'pirate-speak'])
    +      expect(loadCalls[0].nss).to.eql(['translation', 'custom.ns'])
    +      expect(i18n.options.ns.filter(n => n.indexOf('..') > -1 || n === '__proto__')).to.eql([])
    +      expect(i18n.options.ns).to.contain(nsBefore[0])
    +    })
    +  })
    +
    +  describe('cookie SameSite=None enforces Secure', () => {
    +    it('adds Secure automatically when SameSite=None is set', () => {
    +      const ld = new LanguageDetector(i18next.services, {
    +        order: ['cookie'],
    +        cookieSameSite: 'none'
    +      })
    +      const res = { headers: {} }
    +      res.header = (name, value) => { res.headers[name] = value }
    +      ld.cacheUserLanguage({}, res, 'en', ['cookie'])
    +      const cookieStr = String(res.headers['Set-Cookie'])
    +      expect(cookieStr).to.match(/SameSite=None/)
    +      expect(cookieStr).to.match(/Secure/)
    +    })
    +
    +    it('does not force Secure when SameSite is Lax', () => {
    +      const ld = new LanguageDetector(i18next.services, {
    +        order: ['cookie'],
    +        cookieSameSite: 'lax'
    +      })
    +      const res = { headers: {} }
    +      res.header = (name, value) => { res.headers[name] = value }
    +      ld.cacheUserLanguage({}, res, 'en', ['cookie'])
    +      const cookieStr = String(res.headers['Set-Cookie'])
    +      expect(cookieStr).to.match(/SameSite=Lax/)
    +      expect(cookieStr).not.to.match(/Secure/)
    +    })
    +  })
    +})
    
  • .travis.yml+0 11 removed
    @@ -1,11 +0,0 @@
    -sudo: false
    -language: node_js
    -node_js:
    -- '12'
    -- '14'
    -branches:
    -  only:
    -  - master
    -notifications:
    -  email:
    -  - adriano@raiano.ch
    \ No newline at end of file
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.