Internal addresses can pass the Ip validation constraint when you use it to allow only public addresses. If your app uses that check to stop server-side request forgery (SSRF, getting your server to make requests on an attacker's behalf), an attacker can get past it and point your server at internal hosts.

The constraint relied only on PHP's built-in IP range flags, which miss several internal and special ranges and some IPv6 spellings of IPv4 addresses.

Who is affected

Apps on symfony/validator (also part of symfony/symfony) that use #[Assert\Ip] in a filtered mode as a security check: Ip::ALL_ONLY_PUBLIC, Ip::ALL_NO_PRIV, Ip::ALL_NO_RES, or their V4 and V6 forms. The Symfony advisory says the plain V4, V6 and ALL modes do no range filtering at all, so they aren't changed. Results also varied with the PHP version.

What to do

Update to 5.4.56, 6.4.50, 7.4.23 or 8.1.11. If you're on 8.0, update to 8.1.11. The fix also rejects every non-public range in the filtered modes.

Some values that passed before are now rejected. For example, NO_PRIV and NO_RES now behave like ONLY_PUBLIC, so 127.0.0.1 fails NO_PRIV.

Reported by zx (Jace).