Логотип exploitDog
Консоль
Логотип exploitDog

exploitDog

github логотип

GHSA-3cr5-j632-f35r

Опубликовано: 03 июл. 2025
Источник: github
Github: Не прошло ревью

Описание

Null byte termination in hostnames

Summary

fsockopen() doesn't regard hostname as well, hostname is terminated at the null byte. This can cause Server Side Request Forgery in general case.

Details

During fsockopen is being called hostname is passed directly to the low-level C function calls.

/etc/standard/fsock.c:28

static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent) { char *host; size_t host_len; zend_long port = -1; zval *zerrno = NULL, *zerrstr = NULL; double timeout; bool timeout_is_null = 1; #ifndef PHP_WIN32 time_t conv; #else long conv; #endif struct timeval tv; char *hashkey = NULL; php_stream *stream = NULL; int err; char *hostname = NULL; size_t hostname_len; zend_string *errstr = NULL; ZEND_PARSE_PARAMETERS_START(1, 5) Z_PARAM_STRING(host, host_len) Z_PARAM_OPTIONAL Z_PARAM_LONG(port) Z_PARAM_ZVAL(zerrno) Z_PARAM_ZVAL(zerrstr) Z_PARAM_DOUBLE_OR_NULL(timeout, timeout_is_null) ZEND_PARSE_PARAMETERS_END(); // ... stream = php_stream_xport_create(hostname, hostname_len, REPORT_ERRORS, STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, hashkey, &tv, NULL, &errstr, &err);

When fsockopen() is called, it retrieves hostname from first parameter, into host and host_len. host can contain null bytes in the middle of the string, but host_len can be used to prevent unexpected null termination. These two host and host_len is passed to php_stream_xport_create()

/main/streams/transports.c:_php_stream_xporet_create()

orig_path = name; for (p = name; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { n++; } if ((*p == ':') && (n > 1) && !strncmp("://", p, 3)) { protocol = name; name = p + 3; namelen -= n + 3; } else { protocol = "tcp"; n = 3; }

After TCP factory is selected, php_network_getaddresses() is called, but still null bytes or any control characters are not processed. This will lead Server Side Request Forgery.

While other url-related functions like parse_url has processing logic using zend_string type and iscntrl() check. This difference can be used to trigger SSRF in general case.

For example, one developer can write following reasonable code.

<?php $connect_host = "(user_given_host):(user_given_port)"; $host = parse_url($connect_host, PHP_URL_HOST); if(!str_ends_with($host, ".safedomain.com")) die("Wrong host"); $fp = fsockopen($connect_host); ...

When $connect_host is given as localhost\0.safedomain.com, parse_url will return localhost_.safedomain.com as its host, which can pass the security check, but fsockopen() will connect to localhost and occurs server side request forgery.

PoC

<?php $fp = fsockopen("localhost\0.some-domain-for-me.com, 4000); fwrite($fp, "TEST\n"); fclose($fp);

This code will connect to localhost:4000.

Impact

Server Side Request Forgery

Classification

PHP does not usually classify \0 as a security issue because users are expected to sanitize the input. Nevertheless this was considered as a low impact security issue as a precaution for users that do not do that. It also take into account that the patch is simple.

Пакеты

Наименование
Отсутствует
Затронутые версииВерсия исправления

< 8.1.33

8.1.33

Наименование
Отсутствует
Затронутые версииВерсия исправления

< 8.2.29

8.2.29

Наименование
Отсутствует
Затронутые версииВерсия исправления

< 8.3.23

8.3.23

Наименование
Отсутствует
Затронутые версииВерсия исправления

< 8.4.10

8.4.10

EPSS

Процентиль: 10%
0.00037
Низкий

Дефекты

CWE-918

Связанные уязвимости

CVSS3: 3.7
ubuntu
21 день назад

In PHP versions:8.1.* before 8.1.33, 8.2.* before 8.2.29, 8.3.* before 8.3.23, 8.4.* before 8.4.10 some functions like fsockopen() lack validation that the hostname supplied does not contain null characters. This may lead to other functions like parse_url() treat the hostname in different way, thus opening way to security problems if the user code implements access checks before access using such functions.

CVSS3: 3.7
redhat
21 день назад

In PHP versions:8.1.* before 8.1.33, 8.2.* before 8.2.29, 8.3.* before 8.3.23, 8.4.* before 8.4.10 some functions like fsockopen() lack validation that the hostname supplied does not contain null characters. This may lead to other functions like parse_url() treat the hostname in different way, thus opening way to security problems if the user code implements access checks before access using such functions.

CVSS3: 3.7
nvd
21 день назад

In PHP versions:8.1.* before 8.1.33, 8.2.* before 8.2.29, 8.3.* before 8.3.23, 8.4.* before 8.4.10 some functions like fsockopen() lack validation that the hostname supplied does not contain null characters. This may lead to other functions like parse_url() treat the hostname in different way, thus opening way to security problems if the user code implements access checks before access using such functions.

CVSS3: 3.7
debian
21 день назад

In PHP versions:8.1.* before 8.1.33, 8.2.* before 8.2.29, 8.3.* before ...

suse-cvrf
11 дней назад

Security update for php8

EPSS

Процентиль: 10%
0.00037
Низкий

Дефекты

CWE-918