Pregunta

Teniendo en cuenta ciertos juegos de caracteres de varios bytes, estoy en lo cierto al suponer que el siguiente no se haga lo que se pretende hacer?

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

En particular, si la entrada estaba en un conjunto de caracteres que podría tener un carácter válido como 0xbf5c, por lo que un atacante puede inyectar 0xbf22 para obtener 0xbf5c22, dejando un carácter válido seguido de una comilla doble sin comillas ( ").

¿Hay una manera fácil de mitigar este problema, o estoy entendiendo mal el problema en el primer lugar?

(En mi caso, la cadena va en el atributo de valor de una etiqueta HTML de entrada: ". $ Cadena '" eco input type = valor de "texto" = ">';)

EDIT: Por lo demás, ¿qué pasa con una función como preg_quote ()? No hay argumento charset para ello, por lo que parece totalmente inútil en este escenario. Cuando usted no tiene la opción de limitar el juego de caracteres UTF-8 (sí, eso sería agradable), parece como si realmente están impedidos. Lo que sustituyen y funciones citan están disponibles en ese caso?

¿Fue útil?

Solución

No, tienes razón: Usando una función de cadena singlebyte en una cadena multibyte puede causar un resultado inesperado. Utilice la multibyte funciones de cadena en lugar, por ejemplo mb_ereg_replace o mb_split :

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

Editar He aquí una aplicación mb_replace utilizando la variante dividida unirse a:

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 cuanto a la combinación de parámetros, esta función debe comportarse como el str_replace singlebyte.

Otros consejos

El código es perfectamente seguro con cuerdo multibyte-codificaciones como UTF-8 y EUC-TW, pero peligroso con rotas aquellos como Shift_JIS, GB *, etc. En lugar de pasar por todo el dolor de cabeza y los gastos generales para estar seguro con estas codificaciones heredadas, recomendaría solo soporta solamente UTF-8.

Se puede utilizar cualquiera mb_ereg_replace especificando primero el juego de caracteres con mb_regex_encoding(). Alternativamente, si se utiliza UTF-8, puede utilizar preg_replace con el modificador u.

Por lo que entiendo, gran parte de este tipo de inyección cadena se resuelve mediante la mysql_real_escape_string (); función.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top