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"]
的类型为 string
、int
、float
、bool
或 null
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 ?
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.
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 :
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.