Domanda

In considerazione alcuni set di caratteri multibyte, sono io correggo nel ritenere che quanto segue non fa quello che si intendeva fare?

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

In particolare, se l'ingresso era in un set di caratteri che potrebbe avere un carattere valido come 0xbf5c, quindi un attaccante può iniettare 0xbf22 per ottenere 0xbf5c22, lasciando un carattere valido seguito da un doppio apice non quotate ( ").

C'è un modo semplice per attenuare questo problema, o sto fraintendendo la questione in primo luogo?

(Nel mio caso, la stringa sta andando in l'attributo value di un tag input HTML: ' ". $ String'" echo input type = valore "text" = '>';)

EDIT: Del resto, che dire di una funzione come funzione preg_quote ()? Non c'è alcun argomento charset per essa, a quanto pare totalmente inutile in questo scenario. Quando non si ha la possibilità di limitare charset UTF-8 (sì, sarebbe bello), sembra che si sta davvero portatori di handicap. Ciò che sostituiscono e funzioni citando sono disponibili in quel caso?

È stato utile?

Soluzione

No, hai ragione: Utilizzo di una funzione di stringa singlebyte su una stringa multibyte può causare un risultato inaspettato. Utilizzare il multibyte funzioni stringa invece, per esempio mb_ereg_replace o mb_split :

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

Modifica Ecco un'implementazione mb_replace utilizzando 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;
}

Per quanto riguarda la combinazione di parametri, questa funzione dovrebbe comportarsi come il str_replace singlebyte.

Altri suggerimenti

Il codice è perfettamente sicuro con sano multibyte-codifiche come UTF-8 e EUC-TW, ma pericolosa rotti quelli come Shift_JIS, GB *, ecc Piuttosto che passare attraverso tutto il mal di testa e l'overhead di essere al sicuro con queste codifiche legacy, mi sento di raccomandare solo supporta solo UTF-8.

Si potrebbe utilizzare mb_ereg_replace specificando prima il set di caratteri con mb_regex_encoding(). In alternativa, se si utilizza UTF-8, è possibile utilizzare preg_replace con il modificatore u.

Da quanto ho capito, gran parte di questo tipo di iniezione stringa è risolto dal mysql_real_escape_string (); funzione.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top