Question

Compte tenu de certains jeux, ai-je raison de caractères multi-octets en supposant que ce qui suit ne fait pas ce qu'il était censé faire?

$string = str_replace('"', '\\"', $string);

En particulier, si l'entrée était dans un jeu de caractères qui pourraient avoir un caractère valide comme 0xbf5c, donc un attaquant peut injecter 0xbf22 pour obtenir 0xbf5c22, laissant un caractère valide suivi d'un unquoted guillemet ( ").

Y at-il un moyen facile d'atténuer ce problème, ou que je comprends mal la question en premier lieu?

(Dans mon cas, la chaîne va dans l'attribut de valeur d'une balise d'entrée HTML: ' ". $ String'" echo input type = valeur "text" = '>';)

EDIT: Pour cette question, qu'en fonction comme preg_quote ()? Il n'y a pas argument charset pour elle, il semble tout à fait inutile dans ce scénario. Lorsque vous n'avez la possibilité de limiter charset UTF-8 (oui, ce serait bien), il semble que vous êtes vraiment handicapé. Que remplacer et les fonctions sont disponibles en citant ce cas?

Était-ce utile?

La solution

Non, vous avez raison: l'aide d'une fonction de chaîne singlebyte sur une chaîne de caractères multi-octets peut causer un résultat inattendu. Utilisez le fonctions de chaîne multi-octets au lieu, par exemple mb_ereg_replace ou href="http://php.net/mb_split" rel="noreferrer"> mb_split :

$string = mb_ereg_replace('"', '\\"', $string);
$string = implode('\\"', mb_split('"', $string));

Modifier Voici une implémentation mb_replace en utilisant la variante split-join:

function mb_replace($search, $replace, $subject, &$count=0) {
    if (!is_array($search) && is_array($replace)) {
        return false;
    }
    if (is_array($subject)) {
        // call mb_replace for each single string in $subject
        foreach ($subject as &$string) {
            $string = &mb_replace($search, $replace, $string, $c);
            $count += $c;
        }
    } elseif (is_array($search)) {
        if (!is_array($replace)) {
            foreach ($search as &$string) {
                $subject = mb_replace($string, $replace, $subject, $c);
                $count += $c;
            }
        } else {
            $n = max(count($search), count($replace));
            while ($n--) {
                $subject = mb_replace(current($search), current($replace), $subject, $c);
                $count += $c;
                next($search);
                next($replace);
            }
        }
    } else {
        $parts = mb_split(preg_quote($search), $subject);
        $count = count($parts)-1;
        $subject = implode($replace, $parts);
    }
    return $subject;
}

En ce qui concerne la combinaison de paramètres, cette fonction doit se comporter comme le str_replace de singlebyte.

Autres conseils

Le code est parfaitement sûr avec sain d'esprit multi-octets codages comme UTF-8 et EUC-TW, mais dangereux avec cassés les comme Shift_JIS, GB *, etc., plutôt que de passer par tous les maux de tête et des frais généraux pour être en sécurité avec ces anciens codages, je recommande simplement soutenir que UTF-8.

Vous pouvez utiliser soit mb_ereg_replace d'abord spécifier le charset avec mb_regex_encoding(). Alternativement, si vous utilisez UTF-8, vous pouvez utiliser preg_replace avec le modificateur u.

D'après ce que je comprends, une grande partie de ce type d'injection de chaîne est résolu par le mysql_real_escape_string (); une fonction.

http://php.net/manual/en/ function.mysql-real-évasion-string.php

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top