substr_replace str_replace special saltos reemplazar preg_replace linea espacios eliminar characters blanco array php multibyte

php - special - ¿Str_replace() en cadenas de varios bytes es peligroso?



trim array php (4)

Dados ciertos conjuntos de caracteres multibyte, ¿tengo razón al suponer que lo siguiente no hace lo que estaba destinado a 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, 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 primer lugar?

(En mi caso, la cadena entra en el atributo de valor de una etiqueta de entrada HTML: echo ''input type = "text" value = "''. $ String. ''">'';)

EDIT: Para el caso, ¿qué pasa con una función como preg_quote ()? No hay un argumento de conjunto de caracteres para ello, por lo que parece totalmente inútil en este escenario. Cuando NO tienes la opción de limitar el juego de caracteres a UTF-8 (sí, eso sería bueno), parece que estás realmente discapacitado. ¿Qué funciones de reemplazar y citar están disponibles en ese caso?


El código es perfectamente seguro con codificaciones multibyte sanas como UTF-8 y EUC-TW, pero peligroso con las rotas como Shift_JIS, GB *, etc. Recomendaría solo soportar solo UTF-8.


No, tienes razón: el uso de una función de cadena de un solo byte en una cadena de varios bytes puede provocar un resultado inesperado. Utilice las funciones de cadena multibyte en su lugar, por ejemplo mb_ereg_replace o mb_split :

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

Editar Aquí hay una implementación de mb_replace utilizando la variante de unión dividida:

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 debería comportarse como el single_byte str_replace .



Puedes usar mb_ereg_replace especificando primero el conjunto de caracteres con mb_regex_encoding() . Alternativamente, si usa UTF-8, puede usar preg_replace con el modificador u .