Что делает FILTER_SANITIZE_STRING?

24

Там, как миллион Q & A, которые объясняют параметры типа FILTER_FLAG_STRIP_LOW, но что делает FILTER_SANITIZE_STRING самостоятельно, без каких-либо параметров? Он просто фильтрует теги?

Теги:
sanitization

2 ответа

46
Лучший ответ

Согласно Руководство по 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 вместо пустых строк.
  • 14
    как обычно, определение W3School совершенно бесполезно. без определения того, что представляют собой «нежелательные персонажи», это может сделать практически все в соответствии с ними.
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: &#34; 8. Single quote: &#39;
    • 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: <?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: &#34; 8. Single quote: &#39;
    • 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: &#34; 8. Single quote: &#39;
    • 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: &#195;&#135;&#195;&#188;&#195;&#169; 3. PHP tag: 4. HTML tag: var i = 0; 5. Ampersand: & 6. Backtick: ` 7. Double quote: &#34; 8. Single quote: &#39;
    • 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: &#38; 6. Backtick: ` 7. Double quote: &#34; 8. Single quote: &#39;

Кроме того, для флагов FILTER_FLAG_STRIP_LOW и FILTER_FLAG_ENCODE_LOW, так как мой Bash не отображает эти символы, я проверил с использованием символа звонка (, ASCII 007) и расширения Restman Chrome, который:

  • без любого из этих флагов символ сохраняется
  • с FILTER_FLAG_STRIP_LOW, он удален
  • с FILTER_FLAG_ENCODE_LOW, он закодирован до &#7;
  • 2
    Примечание: вы можете запустить PHP из командной строки
  • 0
    Как насчет обратной косой черты?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню