web-dev-qa-db-fra.com

Que fait FILTER_SANITIZE_STRING?

Il y a un million de questions/réponses qui expliquent les options comme FILTER_FLAG_STRIP_LOW, mais qu'est-ce que FILTER_SANITIZE_STRING faire seul, sans aucune option? Filtre-t-il simplement les balises?

39
user1322720

Selon PHP Manual :

Supprimez les balises, supprimez ou encodez éventuellement des caractères spéciaux.

Selon W3Schools :

The FILTER_SANITIZE_STRING filtre les bandes ou encode les caractères indésirables.

Ce filtre supprime les données potentiellement dangereuses pour votre application. Il est utilisé pour supprimer les balises et supprimer ou encoder les caractères indésirables.

Maintenant, cela ne nous dit pas grand-chose. Allons voir quelques sources 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         },  
    /*...*/

Voyons maintenant comment php_filter_string est défini.
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;
    }
}

Je vais sauter les drapeaux de commentaires car ils sont déjà expliqués sur Internet, comme vous l'avez dit, et me concentrer sur ce qui est toujours effectué à la place, ce qui n'est pas si bien documenté.

Première - php_filter_strip. Cela ne fait pas grand-chose, prend simplement les drapeaux que vous passez à la fonction et les traite en conséquence. Il fait le truc bien documenté.

Ensuite, nous construisons une sorte de carte et appelons php_filter_encode_html. C'est plus intéressant: il convertit des trucs comme ", ', & et les caractères avec leurs ASCII inférieurs à 32 et supérieurs à 127 pour les entités HTML, donc & dans votre chaîne devient &. Encore une fois, il utilise des drapeaux pour cela.

Ensuite, nous recevons un appel à php_strip_tags_ex, qui supprime simplement les balises HTML, XML et PHP (selon sa définition dans /ext/standard/string.c) et supprime NULL octets, comme le dit le commentaire.

Le code qui le suit est utilisé pour la gestion des chaînes internes et ne fait pas vraiment de nettoyage. Eh bien, pas exactement - en passant le drapeau non documenté FILTER_FLAG_EMPTY_STRING_NULL renverra NULL si la chaîne filtrée est vide, au lieu de renvoyer juste une chaîne vide, mais ce n'est pas vraiment très utile. Un exemple:

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) ""

Il n'y a pas grand-chose de plus, donc le manuel était assez correct - pour résumer:

  • Toujours: supprimer HTML, XML et PHP, supprimer NULL octets.
  • FILTER_FLAG_NO_ENCODE_QUOTES - Ce drapeau n'encode pas les guillemets.
  • FILTER_FLAG_STRIP_LOW - Supprimer les caractères avec ASCII inférieure à 32.
  • FILTER_FLAG_STRIP_HIGH - Supprimer les caractères avec ASCII valeur supérieure à 127.
  • FILTER_FLAG_ENCODE_LOW - Encode les caractères avec ASCII valeur inférieure à 32.
  • FILTER_FLAG_ENCODE_HIGH - Encode les caractères avec ASCII valeur supérieure à 127.
  • FILTER_FLAG_ENCODE_AMP - Encode le caractère & en & (ne pas &).
  • FILTER_FLAG_EMPTY_STRING_NULL - Retourne NULL au lieu de chaînes vides.
62
rr-

Je ne savais pas si "supprimer les balises" signifie uniquement les caractères <>, Et s'il préserve le contenu entre les balises, par exemple la chaîne "Bonjour!" de <b>Hello!</b>, j'ai donc décidé de vérifier. Voici les résultats, en utilisant PHP 7.1.5 (et Bash pour la ligne de commande):

 curl --data-urlencode 'my-input ='\
 '1. ASCII b/n 32 et 127: ABC abc 012 '\ 
' 2. ASCII supérieur à 127: Çüé '\ 
 '3. PHP: <? Php $ i = 0;?>'\
 '4. Balise HTML: <script type = "text/javascript"> var i = 0; </script> '\ 
' 5. Esperluette: '\ 
' 6. Backtick: `'\ 
' 7. Citation double:" '\ 
 '8. Citation unique:' "'"\
 Http: //localhost/sanitize.php 
    • sanitize.php: <?php echo filter_input(INPUT_POST,'my-input', FILTER_SANITIZE_STRING);
    • sortie: 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);
    • sortie: 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);
    • sortie: 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);
    • sortie: 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);
    • sortie: 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);
    • sortie: 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;

De plus, pour les drapeaux FILTER_FLAG_STRIP_LOW FILTER_FLAG_ENCODE_LOW, puisque mon Bash n'affiche pas ces caractères, j'ai vérifié en utilisant le caractère de cloche (# 7 ;, ASCII 007) et Restman Chrome extension qui:

  • sans aucun de ces drapeaux, le personnage est conservé
  • avec FILTER_FLAG_STRIP_LOW, il est supprimé
  • avec FILTER_FLAG_ENCODE_LOW, il est encodé en &#7;
8
Jan Żankowski