Bueno estoy haciendo un formulario para la publicación de noticias en el que estoy teniendo en cuenta muchos temas de seguridad web, una de ellas vi que era la Inyección HTML y decidí filtrar las etiquetas sin perderlas. Hay muchas cosas que desconozco y otras que deseo aprender, así que todo lo que podáis recomendarme sera bienvenido y agradecido. :)
La siguiente función filtra el texto introducido y lee el contenido de las etiquetas encontradas, los "menor que" y "mayor que" sueltos, si la información del interior de las etiquetas encontrada es referente a las etiquetas permitidas (En mi caso "a href", "/a" y "img src") pues no las toca, pero si son de cualquier otra cosa, las cambiara por sus nombres HTML impidiendo el uso de etiquetas como <script> u otras.
Creo que podría ampliarlo todavía más, poniendo que la etiqueta "a href" si no encuentra </a> se cierre sola y esas cosas, pero por el momento me conformo con esto ya que su misión principal esta cumplida o eso creo, eso os lo dejo a vosotros para que lo juzguéis.
Código PHP:
function filtro_publicacion(&$valor){
$valor_array = str_split($valor);
$o = 0;
$tag_composition = '';
$mayor_aux = 0;
foreach ($valor_array as $valor_array_aux){
if($valor_array_aux == "<"){ //Si existe < entonces buscara más adelante un >
$tag[] = $o; //Guarda la posicion de < en la primera iteracion
$metating[] = $valor_array_aux;
}
if($valor_array_aux == ">"){
$tag[] = $o; //Guarda la posicion de > en la primera iteracion
$metating[] = $valor_array_aux;
}
$o++;
}
$count_tag = count($tag) - 1; // Se hace un menos 1 al count para que no guarde un valor de más que no existe
for ($i = 0; $i <= $count_tag; $i++){
if ($metating[$i] == "<"){ //Obtiene posicion del tag <
$ad = 1 + $i;
if ($metating[$ad] == ">"){ // Obtiene posicion del tag >
$minor = $tag[$i] + 1 ; // Obtiene posicion del contenido interior desde <
$minor_aux = $i; // Vuelve a su posicion en <
$mayor = $tag[$ad] - 1; // Obtiene posicion del contenido interior desde >
$mayor_aux = $ad; // Vuelve a su posicion en >
while ($minor <= $mayor){ // Obtiene desde punto A a punto B toda la informacion del interior de las etiquetas
$tag_composition .= $valor_array[$minor];
$minor++;
}
if (strpos($tag_composition, "img src") !== FALSE OR // Si se encuentra las palabras dentro de la etiqueta
strpos($tag_composition, "a href") !== FALSE OR
strpos($tag_composition, "/a") !== FALSE) // Esto se puede ampliar con las palabras reservadas que se quieran
{
// Primer caso si estan las palabras reservadas
}else{
// Segundo caso no se encuentran las palabras reservadas
// Las etiquetas osea solo < > al no ser las palabras reservadas deseadas se cambian por su nombre de entidad de HTML en ASCII
if ($metating[$minor_aux] == "<"){
$position_valor_array = $tag[$minor_aux];
$valor_array[$position_valor_array] = "<";
}
if($metating[$mayor_aux] == ">"){
$position_valor_array = $tag[$mayor_aux];
$valor_array[$position_valor_array] = ">";
}
}
$tag_composition = ''; //Se vacia aqui la variable para que no mezcle la informacion a verificar y sea unica
}else{
//Cambia los solitarios <
$position_valor_array = $tag[$i];
$valor_array[$position_valor_array] = "<";
}
}
if ($metating[$i] != "<"){
if ($i == 0 AND $tag[$i] == ">"){
//Cambia el solitario > solo para el 0
$position_valor_array = $tag[$i];
$valor_array[$position_valor_array] = ">";
}
if ($tag[$i] != $tag[$mayor_aux]){
// Evitar que pase por encima de los > ya verificados
// Cambia los solitarios >
$position_valor_array = $tag[$i];
$valor_array[$position_valor_array] = ">";
}
}
}
$valor = implode($valor_array);
return ($valor);
}
Un saludo y gracias por vuestro tiempo, dejadme algún comentario si lo habéis probado, si os a gustado o que cambiaríais del código, me gustaría saber. ;)