Там, как миллион Q & A, которые объясняют параметры типа FILTER_FLAG_STRIP_LOW
, но что делает FILTER_SANITIZE_STRING
самостоятельно, без каких-либо параметров? Он просто фильтрует теги?
Что делает FILTER_SANITIZE_STRING?
Ответ 1
Согласно Руководство по PHP:
Разделите теги, произвольно разделите или закодируйте специальные символы.
Согласно W3Schools:
The FILTER_SANITIZE_STRING
фильтрует полосы или кодирует нежелательные символы.Этот фильтр удаляет данные, потенциально опасные для вашего приложения. Он используется для снятия тегов и удаления или кодирования нежелательных символов.
Теперь это не говорит нам много. Отпустите некоторые источники PHP.
ext/filter/filter.c
:
static const filter_list_entry filter_list[] = {
/*...*/
{ "string", FILTER_SANITIZE_STRING, php_filter_string },
{ "stripped", FILTER_SANITIZE_STRING, php_filter_string },
{ "encoded", FILTER_SANITIZE_ENCODED, php_filter_encoded },
/*...*/
Теперь давайте посмотрим, как определяется php_filter_string
. ext/filter/sanitizing_filters.c
:
/* {{{ php_filter_string */
void php_filter_string(PHP_INPUT_FILTER_PARAM_DECL)
{
size_t new_len;
unsigned char enc[256] = {0};
/* strip high/strip low ( see flags )*/
php_filter_strip(value, flags);
if (!(flags & FILTER_FLAG_NO_ENCODE_QUOTES)) {
enc['\''] = enc['"'] = 1;
}
if (flags & FILTER_FLAG_ENCODE_AMP) {
enc['&'] = 1;
}
if (flags & FILTER_FLAG_ENCODE_LOW) {
memset(enc, 1, 32);
}
if (flags & FILTER_FLAG_ENCODE_HIGH) {
memset(enc + 127, 1, sizeof(enc) - 127);
}
php_filter_encode_html(value, enc);
/* strip tags, implicitly also removes \0 chars */
new_len = php_strip_tags_ex(Z_STRVAL_P(value), Z_STRLEN_P(value), NULL, NULL, 0, 1);
Z_STRLEN_P(value) = new_len;
if (new_len == 0) {
zval_dtor(value);
if (flags & FILTER_FLAG_EMPTY_STRING_NULL) {
ZVAL_NULL(value);
} else {
ZVAL_EMPTY_STRING(value);
}
return;
}
}
Я пропущу флаги комментариев, поскольку они уже объясняются в Интернете, как вы сказали, и сосредоточены на том, что всегда выполняется вместо этого, что не так хорошо документировано.
Сначала - php_filter_strip
. Это не делает много, просто берет флаги, которые вы передаете функции, и обрабатывает их соответственно. Это хорошо документированный материал.
Затем мы строим какое-то отображение и вызываем php_filter_encode_html
. Это более интересно: он преобразует такие вещи, как "
, '
, &
и символы со своими кодами ASCII ниже 32 и выше 127 в HTML-объекты, поэтому &
в вашей строке становится &
. Опять же, для этого используются флаги.
Затем мы получаем вызов php_strip_tags_ex
, который просто разбивает теги HTML, XML и PHP (в соответствии с его определением в /ext/standard/string.c
) и удаляет NULL байты, как говорится в комментарии.
Код, который следует за ним, используется для внутреннего управления строкой и не выполняет никакой санитарной обработки. Ну, не совсем - передача недокументированного флага FILTER_FLAG_EMPTY_STRING_NULL
вернет NULL
, если очищенная строка пуста, вместо того, чтобы возвращать только пустую строку, но это не так уж и полезно. Пример:
var_dump(filter_var("yo", FILTER_SANITIZE_STRING, FILTER_FLAG_EMPTY_STRING_NULL));
var_dump(filter_var("\0", FILTER_SANITIZE_STRING, FILTER_FLAG_EMPTY_STRING_NULL));
var_dump(filter_var("yo", FILTER_SANITIZE_STRING));
var_dump(filter_var("\0", FILTER_SANITIZE_STRING));
→
string(2) "yo"
NULL
string(2) "yo"
string(0) ""
Прошло немного больше, поэтому руководство было довольно корректным - подвести итог:
- Всегда: стричьте теги HTML, XML и PHP, разделите NULL байты.
-
FILTER_FLAG_NO_ENCODE_QUOTES
- этот флаг не кодирует кавычки. -
FILTER_FLAG_STRIP_LOW
- разделите символы со значением ASCII ниже 32. -
FILTER_FLAG_STRIP_HIGH
- разделите символы с значком ASCII выше 127. -
FILTER_FLAG_ENCODE_LOW
- Кодировать символы со значением ASCII ниже 32. -
FILTER_FLAG_ENCODE_HIGH
- Кодировать символы со значением ASCII выше 127. -
FILTER_FLAG_ENCODE_AMP
- Кодировать символ и символ&
(не&
). -
FILTER_FLAG_EMPTY_STRING_NULL
- ВернутьNULL
вместо пустых строк.
Ответ 2
Я не был уверен, что "дескрипторы" означают только символы <
>
, и если он сохраняет контент между тегами, например. строка "Привет!" от <b>Hello!</b>
, поэтому я решил проверить. Вот результаты, используя PHP 7.1.5 (и Bash для командной строки):
curl --data-urlencode 'my-input='\ '1. ASCII b/n 32 and 127: ABC abc 012 '\ '2. ASCII higher than 127: Çüé '\ '3. PHP tag: <?php $i = 0; ?> '\ '4. HTML tag: <script type="text/javascript">var i = 0;</script> '\ '5. Ampersand: & '\ '6. Backtick: ` '\ '7. Double quote: " '\ '8. Single quote: '"'" \ http://localhost/sanitize.php
-
- sanitize.php:
<?php echo filter_input(INPUT_POST,'my-input', FILTER_SANITIZE_STRING);
- вывод:
1. ASCII b/n 32 and 127: ABC abc 012 2. ASCII higher than 127: Çüé 3. PHP tag: 4. HTML tag: var i = 0; 5. Ampersand: & 6. Backtick: ` 7. Double quote: " 8. Single quote: '
- sanitize.php:
-
- sanitize.php:
<?php echo filter_input(INPUT_POST,'my-input', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
- вывод:
1. ASCII b/n 32 and 127: ABC abc 012 2. ASCII higher than 127: Çüé 3. PHP tag: 4. HTML tag: var i = 0; 5. Ampersand: & 6. Backtick: ` 7. Double quote: " 8. Single quote: '
- sanitize.php:
-
- sanitize.php:
<?php echo filter_input(INPUT_POST,'my-input', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
- вывод:
1. ASCII b/n 32 and 127: ABC abc 012 2. ASCII higher than 127: 3. PHP tag: 4. HTML tag: var i = 0; 5. Ampersand: & 6. Backtick: ` 7. Double quote: " 8. Single quote: '
- sanitize.php:
-
- sanitize.php:
<?php echo filter_input(INPUT_POST,'my-input', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_BACKTICK);
- вывод:
1. ASCII b/n 32 and 127: ABC abc 012 2. ASCII higher than 127: Çüé 3. PHP tag: 4. HTML tag: var i = 0; 5. Ampersand: & 6. Backtick: 7. Double quote: " 8. Single quote: '
- sanitize.php:
-
- sanitize.php:
<?php echo filter_input(INPUT_POST,'my-input', FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_HIGH);
- вывод:
1. ASCII b/n 32 and 127: ABC abc 012 2. ASCII higher than 127: Çüé 3. PHP tag: 4. HTML tag: var i = 0; 5. Ampersand: & 6. Backtick: ` 7. Double quote: " 8. Single quote: '
- sanitize.php:
-
- sanitize.php:
<?php echo filter_input(INPUT_POST,'my-input', FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_AMP);
- вывод:
1. ASCII b/n 32 and 127: ABC abc 012 2. ASCII higher than 127: Çüé 3. PHP tag: 4. HTML tag: var i = 0; 5. Ampersand: & 6. Backtick: ` 7. Double quote: " 8. Single quote: '
- sanitize.php:
Кроме того, для флагов FILTER_FLAG_STRIP_LOW и FILTER_FLAG_ENCODE_LOW, так как мой Bash не отображает эти символы, я проверил с использованием символа звонка (, ASCII 007) и расширения Restman Chrome, который:
- без любого из этих флагов символ сохраняется
- с FILTER_FLAG_STRIP_LOW, он удален
- с FILTER_FLAG_ENCODE_LOW, он закодирован до