Skip to content

Filter bypass in filter_var (FILTER_VALIDATE_URL)

Moderate
smalyshev published GHSA-w8qr-v226-r27w Jun 9, 2024

Package

No package listed

Affected versions

7.3.27 - 7.3.33, 7.4.15 - 7.4.33, 8.0.2 - 8.0.30, 8.1.0 - 8.1.28, 8.2.0 - 8.2.19, 8.3.0 - 8.3.7

Patched versions

8.1.29, 8.2.20, 8.3.8.

Description

Summary

An early-return in filter_var (FILTER_VALIDATE_URL) will result in invalid user information (username + password part of URLs) being treated as valid user information.

This causes the same problems as CVE-2020-7071, but with IPv6 host parts.

Details

The function php_filter_validate_url in php-src/ext/filter/logical_filters.c contains the logic for validating URLs.

For HTTP-IPv6 addresses the implementation contains an early return statement that results in further checks on the user_info being skipped.
The offending return statement is at: https://github.com/php/php-src/blob/master/ext/filter/logical_filters.c#L618

This results in invalid user information being passed as valid for URLs with IPv6 Hosts.

Fix: Restructuring the code to include the user_info checks if the IPv6-host part is correct.
This could be done by only return "SUCCESS" if the end of the function is reached.

PoC

To prove the user info check was skipped I looked for a character that is not allowed in usernames. (Based on the validation code in is_userinfo_valid)
I chose [.
The following statements show that the handling of the URLs is different if the "host" part of the URL is changed.

var_dump(filter_var("http://t[[email protected]", FILTER_VALIDATE_URL));
var_dump(filter_var("http://t[est@[::1]", FILTER_VALIDATE_URL));

Output for 7.3.27 - 7.3.33, 7.4.15 - 7.4.33, 8.0.2 - 8.0.30, 8.1.0 - 8.1.28, 8.2.0 - 8.2.19, 8.3.0 - 8.3.7

bool(false)
string(18) "http://t[est@[::1]"

Output for 7.3.26, 7.4.14, 8.0.1 (CVE-2020-7071 was patched here!)

bool(false)
bool(false)

Output for 5.2.0 - 5.2.12, 5.3.0 - 5.3.1, 7.0.0 - 7.0.33, 7.1.0 - 7.1.33, 7.2.0 - 7.2.34, 7.3.0 - 7.3.25, 7.4.0 - 7.4.13, 8.0.0

string(22) "http://t[[email protected]"
string(18) "http://t[est@[::1]"

Output for 5.2.13 - 5.2.17, 5.3.2 - 5.3.29, 5.4.0 - 5.4.45, 5.5.0 - 5.5.38, 5.6.0 - 5.6.40

string(22) "http://t[[email protected]"
bool(false)

Impact

This bug impacts users that expect only completely valid URLs to be returned by filter_var (FILTER_VALIDATE_URL).
As this function is meant to validate user supplied strings this will be exposed to raw user input often.

As this is almost the same vulnerability as CVE-2020-7071 this should also have a MEDIUM impact.

Related info:
Bugfix for invalid usernames: https://bugs.php.net/bug.php?id=77423 (contains another example POC)

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
Low
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N

CVE ID

CVE-2024-5458

Weaknesses

No CWEs

Credits