recherche

Maison  >  Questions et réponses  >  le corps du texte

PHP : Gestion des tableaux (inattendus) dans la saisie utilisateur

J'ai récemment découvert que l'envoi de variables contenant des tableaux "inattendus" (au lieu de chaînes) peut entraîner des erreurs fatales ou d'autres comportements indésirables. Exemple :

Nous avons le tableau suivant :

$list = array(
"a" => "first",
"b" => "second"
);

L'utilisateur envoie $_REQUEST["key"] qui servira à retrouver un élément dans cette liste :

echo ($list[$_REQUEST["key"]] ?? null);

Si $_REQUEST["key"] 的类型为 stringintfloatboolnull est de type string, int, float, bool ou null , le script affichera les entrées trouvées ou n'affichera rien (= null). C'est le comportement souhaité.

Si $_REQUEST["key"]array est un tableau, le script s'arrêtera avec une erreur fatale.


Maintenant, la solution évidente consiste à ajouter des milliers de vérifications de type (is_scalar()!is_array()) dans tout le code. Mais je me demande si les alternatives suivantes semblent raisonnables du point de vue de la sécurité :

Au début de chaque requête, le script suivant s'exécutera :

$_COOKIE = array_map(function($e) { return (is_array($e) ? json_encode($e, JSON_INVALID_UTF8_IGNORE) : $e); }, $_COOKIE);
$_REQUEST = array_map(function($e) { return (is_array($e) ? json_encode($e, JSON_INVALID_UTF8_IGNORE) : $e); }, $_REQUEST);
$_POST = array_map(function($e) { return (is_array($e) ? json_encode($e, JSON_INVALID_UTF8_IGNORE) : $e); }, $_POST);
$_GET = array_map(function($e) { return (is_array($e) ? json_encode($e, JSON_INVALID_UTF8_IGNORE) : $e); }, $_GET);

Cela désactive efficacement l'envoi de la baie au serveur. Si des positions dans le tableau de codes sont réellement nécessaires, elles seront décodées manuellement à l'aide de json_decode() .

Est-ce une bonne idée ?

P粉547362845P粉547362845240 Il y a quelques jours553

répondre à tous(1)je répondrai

  • P粉668113768

    P粉6681137682024-04-02 14:31:09

    Vous décodez manuellement chaque variable d'entrée pour éviter de valider manuellement chaque variable d'entrée. Pour moi, c'est le même désagrément, mais plus déroutant, moins performant et comporte de nouveaux bugs (par exemple, json_encode() se brisera si l'entrée n'est pas UTF-8 valide).

    En général, il vaut la peine d'être explicite sur les entrées de votre candidature. S'assurer que vous utilisez un ensemble de variables connues dans un état connu peut réellement vous faire gagner du temps et éviter des problèmes.

    $key = isset($_REQUEST['key']) && is_string($_REQUEST['key']) ? $_REQUEST['key'] : null;
    $item = $list[$key] ?? null;

    Si TypeError est votre seule préoccupation, vous pouvez tout envelopper dans un bloc try/catch.

    Vous pouvez utiliser des fonctions pour éviter la duplication de code :

    function get(string $name, ?string $default = null): ?string
    {
        if (isset($_REQUEST[$name]) && is_string($_REQUEST[$name])) {
            return $_REQUEST[$name];
        }
        return $default;
    }

    Vous pouvez créer un framework de validation ou utiliser un framework tiers.

    Il y a beaucoup de choses que je fais avant de jouer avec toutes les entrées, juste pour éviter des cas particuliers.

    répondre
    0
  • Annulerrépondre