Что вызывает фильтрацию значений null byte в запросе?
при попытке укрепить веб-приложение PHP против отравление нулевым байтом, я заметил, что у меня было чертовски много времени на самом деле отправка нулевого байта в моем запросе.
используя cURL, я, наконец, смог найти способ отправить нулевые байты в моих запросах, но я заметил что-то очень странное: никакие параметры запроса, значения которых включают нулевой байт, никогда не достигают моего PHP-приложения.
в качестве доказательства концепции я создал файл с именем test.php
на мой сервер:
<?php echo json_encode($_GET), PHP_EOL;
вот результат некоторых запросов к этому скрипту:
> curl 'http://localhost/test.php?foo=bar&baz=nu%00ll' {"foo":"bar"} > curl 'http://localhost/test.php?foo=bar&b%00az=null' {"foo":"bar","b":"null"}
похоже, что ключи усекаются в нулевом байте, и если значение содержит нулевой байт, параметр полностью удаляется из массива запросов.
используя print_r()
дает похожие результаты:
<?php print_r($_GET);
> curl 'http://localhost/test.php?foo=bar&baz=nu%00ll' Array ( [foo] => bar ) > curl 'http://localhost/test.php?foo=bar&b%00az=null' Array ( [foo] => bar [b] => null )
то же самое происходит, если я изменяю свой скрипт и скручиваю запросы на использование $_POST
.
не то, чтобы я жалуюсь, но я делаю нужно знать, почему это происходит, чтобы я мог убедиться, что каждый веб-сервер настроен правильно.
что вызывает такое поведение?
> php -v PHP 5.3.3 (cli) (built: Jul 3 2012 16:40:30) Copyright (c) 1997-2010 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies with Suhosin v0.9.29, Copyright (c) 2007, by SektionEins GmbH
4 ответов
сначала отключите Suhosin. Он уже позаботился об этом.
пока вы включили его, вы не можете вводить нулевые байты так легко.
Я указываю вам на строку 1010 из /main / SAPI.c исходного кода PHP.
SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC)
{
if (sapi_module.getenv) {
char *value, *tmp = sapi_module.getenv(name, name_len TSRMLS_CC);
if (tmp) {
value = estrdup(tmp);
} else {
return NULL;
}
if (sapi_module.input_filter) {
sapi_module.input_filter(PARSE_ENV, name, &value, strlen(value), NULL TSRMLS_CC);
}
return value;
}
return NULL;
}
estrdup () - #defined to _estrdup (), который находится в строке 396 /Zend/zend_alloc.c и использует как стандартные библиотечные функции strlen (), так и memcpy () для выполнения своих заявок. В основном estrdup () будет копировать только до нулевого байта.
во многих языках, нулевой байт символизирует конец строки. Я бы отправил данные как hex и переинтерпретировал их на стороне сервера. Я не думаю, что GET поддерживает binary.
var_dump($your_url);
если он содержит уродливые / нулевые символы, попробуйте TRIM()
это на первый взгляд.