{"id":"CVE-2026-44492","aliases":["GHSA-pjwm-pj3p-43mv"],"url":"https://o3.security/vulnerability/CVE-2026-44492","summary":"Axios: shouldBypassProxy does not recognize IPv4-mapped IPv6 addresses, allowing NO_PROXY bypass (incomplete fix for CVE-2025-62718)","details":"### Summary\nshouldBypassProxy, introduced in v1.15.0 to fix CVE-2025-62718, does not normalise IPv4-mapped IPv6 addresses. When NO_PROXY lists an IPv4 address such as `127.0.0.1` or `169.254.169.254`, a request URL using the IPv4-mapped IPv6 form (`::ffff:7f00:1`, `::ffff:a9fe:a9fe`) still routes through the configured proxy. Node.js resolves these addresses to the underlying IPv4 host, so the request reaches the internal service via the proxy rather than being blocked.\n\n### Details\nlib/helpers/shouldBypassProxy.js (v1.15.0):                                                                                                                                   \n\n```javascript                                                                                                                                                                              \n  const LOOPBACK_ADDRESSES = new Set(['localhost', '127.0.0.1', '::1']);                                                                                                      \n  const isLoopback = (host) => LOOPBACK_ADDRESSES.has(host);                                                                                                                    \n                                                                                                                                                                                \n  // normalizeNoProxyHost strips brackets and trailing dots, but not ::ffff: prefix                                                                                             \n  return hostname === entryHost || (isLoopback(hostname) && isLoopback(entryHost));                                                                                             \n```\n                                                                                                                                                                                \nThe WHATWG URL parser canonicalises `http://[::ffff:127.0.0.1]/` to hostname `[::ffff:7f00:1]`. After bracket-stripping: `::ffff:7f00:1`. This string does not match 127.0.0.1 in NO_PROXY and is not in LOOPBACK_ADDRESSES, so shouldBypassProxy returns false and the proxy is used.  proxy-from-env (called before shouldBypassProxy) has the same gap - it does not equate ::ffff:7f00:1 with 127.0.0.1 - so neither layer catches the bypass.\n\n### PoC\n```javascript\n\n// NO_PROXY=127.0.0.1,localhost,::1  HTTP_PROXY=http://attacker:8080\nimport shouldBypassProxy from 'axios/lib/helpers/shouldBypassProxy.js';                                                                                                       \n                                                                                                                                                                              \n// All three should return true (bypass proxy). Only the first two do.                                                                                                        \nconsole.log(shouldBypassProxy('http://127.0.0.1/'));          // true  [OK]                                                                                                     \nconsole.log(shouldBypassProxy('http://[::1]/'));               // true  [OK]                                                                                                     \nconsole.log(shouldBypassProxy('http://[::ffff:127.0.0.1]/')); // false <- bypass                                                                                             \nconsole.log(shouldBypassProxy('http://[::ffff:7f00:1]/'));     // false <- bypass\n\n```                                                                                              \n                                                                                                                                                                              \nNode.js routes ::ffff:7f00:1 to 127.0.0.1:                                                                                                                                    \n\n```                                                                                                                                                                              \n// net.connect({ host: '::ffff:7f00:1', port: 80 }) reaches a service                                                                                                       \n// bound to 127.0.0.1:80 — confirmed on Node.js v24, Linux and macOS.                                                                                                         \n```                                                                                                                                                                              \nCloud metadata SSRF: ::ffff:a9fe:a9fe = ::ffff:169.254.169.254. If NO_PROXY=169.254.169.254 is set to block IMDS access, a request to http://[::ffff:a9fe:a9fe]/latest/meta-data/ bypasses it.                                                                                                                      \n                                                                                                                                                                            \n#### Fix                                                                                                                                                                           \n                                                                                                                                                                            \nCanonicalise IPv4-mapped IPv6 in normalizeNoProxyHost before any comparison:                                                                                                  \n \n ```javascript                                                                                                                                                                           \nconst ipv4MappedDotted = /^::ffff:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$/i;                                                                                                    \nconst ipv4MappedHex    = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i;                                                                                                         \n                                                                                                                                                                              \nfunction hexToIPv4(a, b) {                                                                                                                                                    \n  const hi = parseInt(a, 16), lo = parseInt(b, 16);                                                                                                                           \n  return `${hi >> 8}.${hi & 0xff}.${lo >> 8}.${lo & 0xff}`;                                                                                                                   \n}                                                                                                                                                                             \n                                                                                                                                                                              \nconst normalizeNoProxyHost = (hostname) => {                                                                                                                                  \n  if (!hostname) return hostname;                                                                                                                                           \n  if (hostname[0] === '[' && hostname.at(-1) === ']')\n    hostname = hostname.slice(1, -1);                                                                                                                                         \n  hostname = hostname.replace(/\\.+$/, '').toLowerCase();\n                                                                                                                                                                              \n  let m;                                                                                                                                                                    \n  if ((m = hostname.match(ipv4MappedDotted))) return m[1];                                                                                                                    \n  if ((m = hostname.match(ipv4MappedHex)))    return hexToIPv4(m[1], m[2]);                                                                                                   \n  return hostname;                                                                                                                                                            \n};\n\n```\n\n### Impact\nAny application that sets NO_PROXY to exclude internal or metadata endpoints and uses an HTTP/HTTPS proxy can have those exclusions bypassed by a URL using IPv4-mapped IPv6 notation. The attacker must control the request URL. In cloud environments with instance metadata services, this can lead to credential exfiltration.","published":"2026-06-11T15:29:13.890Z","modified":"2026-09-13T03:30:47.881131682Z","cvss":{"score":8.6,"severity":"HIGH","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N"},"epss":{"score":0.00902,"percentile":0.5806,"asOf":"2026-09-17"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"npm","name":"axios","fixedVersion":"1.16.0"},{"ecosystem":"npm","name":"axios","fixedVersion":"0.32.0"}],"fix":null,"references":[{"type":"WEB","url":"https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-44492.json"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:20889"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:20938"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:27044"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:27063"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:28964"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:29082"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:29197"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:30650"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:30651"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:33005"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:33155"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:33160"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:33163"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:33173"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:33183"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:33574"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:34766"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:36108"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:36611"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:36754"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:36820"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:36882"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:36883"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:40262"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:41031"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:41055"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:41064"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:41066"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:41928"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:41951"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:42078"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:42085"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:42142"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:42146"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:42796"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:43052"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:46885"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:46903"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:50300"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:54188"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:57191"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:59833"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:60520"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:66488"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:66545"},{"type":"ADVISORY","url":"https://access.redhat.com/security/cve/CVE-2026-44492"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/44xxx/CVE-2026-44492.json"},{"type":"ADVISORY","url":"https://github.com/axios/axios/security/advisories/GHSA-pjwm-pj3p-43mv"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-44492"},{"type":"REPORT","url":"https://bugzilla.redhat.com/show_bug.cgi?id=2487938"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-62718"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:40119"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:40138"},{"type":"PACKAGE","url":"https://github.com/axios/axios"},{"type":"WEB","url":"https://access.redhat.com/errata/RHSA-2026:26234"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-09-13T03:30:47.881131682Z"}}