GHSA-2XF4-CG6J-VHGQ

Vulnerability from github – Published: 2026-05-28 19:52 – Updated: 2026-05-28 19:52
VLAI
Summary
symfony/polyfill-intl-idn: xn-- labels with ASCII-only Punycode payloads are treated as equivalent to their decoded form
Details

Description

symfony/polyfill-intl-idn provides a userland implementation of idn_to_utf8() and idn_to_ascii() for runtimes that lack the intl extension. Its Idn::process() method decodes labels prefixed with xn-- using Punycode but never enforces the validity criterion added in UTS #46 revision 33 Section 4 step 4.1.2: after a successful Punycode decode, the result must contain at least one non-ASCII code point.

As a consequence, xn-- labels whose Punycode payload is empty (xn--) or decodes to a string made of only ASCII code points (e.g. xn--kc1zs4-) are accepted by the polyfill while PHP's native ext-intl rejects them with IDNA_ERROR_INVALID_ACE_LABEL. Originally unequal domain names are therefore regarded as equal, which can lead to blacklist bypassing, inconsistent URL parsing and server-side request forgery (similar to CVE-2024-12224).

Example with IDNA_USE_STD3_RULES | IDNA_CHECK_BIDI | IDNA_CHECK_CONTEXTJ | IDNA_NONTRANSITIONAL_TO_ASCII:

Input Polyfill output Native ext-intl output
poc.xn--kc1zs4-.com poc.kc1zs4.com false (errors=1024)
poc.kc1zs4.xn-- poc.kc1zs4. false (errors=1024)

Applications using the polyfill to canonicalise or compare hostnames inherit the inconsistency.

Resolution

Idn::process() now records IDNA_ERROR_INVALID_ACE_LABEL when a Punycode payload decodes to an empty string or to a string containing only ASCII code points, matching the native ext-intl behaviour and UTS #46 revision 33.

The patch for this issue is available here for branch 1.x.

Credits

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

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "symfony/polyfill"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.17.1"
            },
            {
              "fixed": "1.38.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "symfony/polyfill-intl-idn"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.17.1"
            },
            {
              "fixed": "1.38.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-46644"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1289"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-28T19:52:36Z",
    "nvd_published_at": null,
    "severity": "LOW"
  },
  "details": "### Description\n\n`symfony/polyfill-intl-idn` provides a userland implementation of `idn_to_utf8()` and `idn_to_ascii()` for runtimes that lack the `intl` extension. Its `Idn::process()` method decodes labels prefixed with `xn--` using Punycode but never enforces the validity criterion added in UTS #46 revision 33 Section 4 step 4.1.2: after a successful Punycode decode, the result must contain at least one non-ASCII code point.\n\nAs a consequence, `xn--` labels whose Punycode payload is empty (`xn--`) or decodes to a string made of only ASCII code points (e.g. `xn--kc1zs4-`) are accepted by the polyfill while PHP\u0027s native `ext-intl` rejects them with `IDNA_ERROR_INVALID_ACE_LABEL`. Originally unequal domain names are therefore regarded as equal, which can lead to blacklist bypassing, inconsistent URL parsing and server-side request forgery (similar to CVE-2024-12224).\n\nExample with `IDNA_USE_STD3_RULES | IDNA_CHECK_BIDI | IDNA_CHECK_CONTEXTJ | IDNA_NONTRANSITIONAL_TO_ASCII`:\n\n| Input | Polyfill output | Native `ext-intl` output |\n| --- | --- | --- |\n| `poc.xn--kc1zs4-.com` | `poc.kc1zs4.com` | `false` (`errors=1024`) |\n| `poc.kc1zs4.xn--` | `poc.kc1zs4.` | `false` (`errors=1024`) |\n\nApplications using the polyfill to canonicalise or compare hostnames inherit the inconsistency.\n\n### Resolution\n\n`Idn::process()` now records `IDNA_ERROR_INVALID_ACE_LABEL` when a Punycode payload decodes to an empty string or to a string containing only ASCII code points, matching the native `ext-intl` behaviour and UTS #46 revision 33.\n\nThe patch for this issue is available [here](https://github.com/symfony/polyfill/commit/1be936e2491ccebe152bd736dfc91eb1422c8bec) for branch 1.x.\n\n### Credits\n\nSymfony would like to thank Nazy Mad for reporting the issue and Nicolas Grekas for providing the fix.",
  "id": "GHSA-2xf4-cg6j-vhgq",
  "modified": "2026-05-28T19:52:36Z",
  "published": "2026-05-28T19:52:36Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/symfony/polyfill/security/advisories/GHSA-2xf4-cg6j-vhgq"
    },
    {
      "type": "WEB",
      "url": "https://github.com/symfony/polyfill/commit/1be936e2491ccebe152bd736dfc91eb1422c8bec"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/symfony/polyfill-intl-idn/CVE-2026-46644.yaml"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/symfony/polyfill/CVE-2026-46644.yaml"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/symfony/polyfill"
    },
    {
      "type": "WEB",
      "url": "https://symfony.com/cve-2026-46644"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:L/SA:N/E:U",
      "type": "CVSS_V4"
    }
  ],
  "summary": "symfony/polyfill-intl-idn: xn-- labels with ASCII-only Punycode payloads are treated as equivalent to their decoded form"
}



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…