GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration

GHSA-38CX-CQ6F-5755

Vulnerability from github – Published: 2026-06-15 17:31 – Updated: 2026-06-15 17:31
VLAI
Summary
Symfony: IpUtils::PRIVATE_SUBNETS Omits IPv6 Transition Forms (6to4, NAT64, Teredo, IPv4-compatible): SSRF Bypass in NoPrivateNetworkHttpClient
Details

Description

Symfony\Component\HttpClient\NoPrivateNetworkHttpClient is documented as a decorator that blocks requests to private networks by default. The list of blocked subnets (Symfony\Component\HttpFoundation\IpUtils::PRIVATE_SUBNETS on 6.4+, a private constant in NoPrivateNetworkHttpClient on 5.4) enumerates RFC1918, loopback, link-local and IPv4-mapped IPv6 (::ffff:0:0/96) prefixes, but omits the remaining IPv6 transition forms that can embed a private IPv4 destination: 6to4 (2002::/16, RFC 3056), Teredo (2001::/32, RFC 4380), NAT64 (64:ff9b::/96, RFC 6052 and 64:ff9b:1::/48, RFC 8215) and IPv4-compatible IPv6 (::/96, RFC 4291 §2.5.5.1).

IpUtils::checkIp6() is a pure bitwise CIDR comparison against the constants list and never extracts the embedded IPv4, so an attacker who can supply a URL writes the loopback / RFC1918 IPv4 target as e.g. http://[2002:7f00:1::]/ (6to4 → 127.0.0.1), http://[64:ff9b::7f00:1]/ (NAT64 → 127.0.0.1), http://[::7f00:1]/ (IPv4-compatible → 127.0.0.1) or http://[2001::1]/ (Teredo). IpUtils::isPrivateIp() returns false and NoPrivateNetworkHttpClient dispatches the request.

Real-world reachability of the embedded IPv4 depends on the deploy's IPv6 routing (6to4 tunnel interface, upstream NAT64 gateway, kernel handling of IPv4-compatible addresses), but the security boundary the decorator promises — the dispatch decision — is crossed regardless of whether the packet ultimately lands on the embedded IPv4.

Resolution

The private-subnet list now includes ::/96, 2002::/16, 2001::/32, 64:ff9b::/96 and 64:ff9b:1::/48. Blanket blocking of these prefixes matches the policy applied by Chromium and Mozilla's Private Network Access; server-side HTTPS APIs are not legitimately published on these prefixes.

The patches for this issue are available here for branch 5.4 and here for branch 6.4 (and forward-ported to 7.4, 8.0 and 8.1).

Credits

Symfony would like to thank tonghuaroot for reporting the issue and Nicolas Grekas for providing the fix.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "symfony/http-client"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "5.4.0"
            },
            {
              "fixed": "5.4.53"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "symfony/http-foundation"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "6.4.0"
            },
            {
              "fixed": "6.4.41"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "symfony/http-foundation"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "7.0.0"
            },
            {
              "fixed": "7.4.13"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "symfony/http-foundation"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "8.0.0"
            },
            {
              "fixed": "8.0.13"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "symfony/symfony"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "5.4.0"
            },
            {
              "fixed": "5.4.53"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "symfony/symfony"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "6.4.0"
            },
            {
              "fixed": "6.4.41"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "symfony/symfony"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "7.0.0"
            },
            {
              "fixed": "7.4.13"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "symfony/symfony"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "8.0.0"
            },
            {
              "fixed": "8.0.13"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-48736"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-184",
      "CWE-918"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-15T17:31:28Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "### Description\n\n`Symfony\\Component\\HttpClient\\NoPrivateNetworkHttpClient` is documented as a decorator that blocks requests to private networks by default. The list of blocked subnets (`Symfony\\Component\\HttpFoundation\\IpUtils::PRIVATE_SUBNETS` on 6.4+, a private constant in `NoPrivateNetworkHttpClient` on 5.4) enumerates RFC1918, loopback, link-local and IPv4-mapped IPv6 (`::ffff:0:0/96`) prefixes, but omits the remaining IPv6 transition forms that can embed a private IPv4 destination: 6to4 (`2002::/16`, RFC 3056), Teredo (`2001::/32`, RFC 4380), NAT64 (`64:ff9b::/96`, RFC 6052 and `64:ff9b:1::/48`, RFC 8215) and IPv4-compatible IPv6 (`::/96`, RFC 4291 \u00a72.5.5.1).\n\n`IpUtils::checkIp6()` is a pure bitwise CIDR comparison against the constants list and never extracts the embedded IPv4, so an attacker who can supply a URL writes the loopback / RFC1918 IPv4 target as e.g. `http://[2002:7f00:1::]/` (6to4 \u2192 127.0.0.1), `http://[64:ff9b::7f00:1]/` (NAT64 \u2192 127.0.0.1), `http://[::7f00:1]/` (IPv4-compatible \u2192 127.0.0.1) or `http://[2001::1]/` (Teredo). `IpUtils::isPrivateIp()` returns `false` and `NoPrivateNetworkHttpClient` dispatches the request.\n\nReal-world reachability of the embedded IPv4 depends on the deploy\u0027s IPv6 routing (6to4 tunnel interface, upstream NAT64 gateway, kernel handling of IPv4-compatible addresses), but the security boundary the decorator promises \u2014 the dispatch decision \u2014 is crossed regardless of whether the packet ultimately lands on the embedded IPv4.\n\n### Resolution\n\nThe private-subnet list now includes `::/96`, `2002::/16`, `2001::/32`, `64:ff9b::/96` and `64:ff9b:1::/48`. Blanket blocking of these prefixes matches the policy applied by Chromium and Mozilla\u0027s Private Network Access; server-side HTTPS APIs are not legitimately published on these prefixes.\n\nThe patches for this issue are available [here](https://github.com/symfony/symfony/commit/82765368cf74177c36613575182f168a2eb765b2) for branch 5.4 and [here](https://github.com/symfony/symfony/commit/85b831555be8ea1f43bf01078afe87bc4c92f65e) for branch 6.4 (and forward-ported to 7.4, 8.0 and 8.1).\n\n### Credits\n\nSymfony would like to thank tonghuaroot for reporting the issue and Nicolas Grekas for providing the fix.",
  "id": "GHSA-38cx-cq6f-5755",
  "modified": "2026-06-15T17:31:28Z",
  "published": "2026-06-15T17:31:28Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/symfony/symfony/security/advisories/GHSA-38cx-cq6f-5755"
    },
    {
      "type": "WEB",
      "url": "https://github.com/symfony/symfony/commit/82765368cf74177c36613575182f168a2eb765b2"
    },
    {
      "type": "WEB",
      "url": "https://github.com/symfony/symfony/commit/85b831555be8ea1f43bf01078afe87bc4c92f65e"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/symfony/http-client/CVE-2026-48736.yaml"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/symfony/http-foundation/CVE-2026-48736.yaml"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/symfony/symfony/CVE-2026-48736.yaml"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/symfony/symfony"
    },
    {
      "type": "WEB",
      "url": "https://symfony.com/cve-2026-48736"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Symfony: IpUtils::PRIVATE_SUBNETS Omits IPv6 Transition Forms (6to4, NAT64, Teredo, IPv4-compatible): SSRF Bypass in NoPrivateNetworkHttpClient"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

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

Sightings

Author Source Type Date Other

Nomenclature

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

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…