Sunday 26 August 2007

Evitar que envien SPAM desde nuestro site

Dos meses atrás alguien utilizó una de mis páginas web para enviar SPAM masivo desde mi servidor. Me di cuenta porque me venían miles de mails devueltos que me saturaban el buzón de correo continuamente. Con la inestimable ayuda de los responsables técnicos del hosting (www.hospedajeydominios.com) descubrimos donde estaba el agujero, analizando el registro (archivo LOG) de mi cuenta de hosting. Una vez descubierto el "agujero de seguridad" probé 2 ó 3 retoques de mi código PHP para evitar el ataque ;) A continuación doy los detalles.

Problema

Como dije, analizando el archivo del servidor que registra las llamadas a archivos de mi cuenta, descubrimos que alguien utilizaba los enlaces de mi aplicación web para pasar como argumento la dirección URL de una web maliciosa.

Es decir, mi aplicación de PHP utiliza links como éste:

<a href="index.php?pag=productos">productos</a>

y los que enviaban spam lo alteraban por:

index.php?pag=http://pagina.maliciosa.com/envio_spam

simplement llamando a esa dirección desde un navegador, o tal vez a través de alguna aplicación que hace las llamadas de forma automatica cada cierto tiempo. La cuestión es que cada vez que ellos llamaban a mi archivo index.php pasandole esa URL como argumento, mi servidor enviaba miles de mails de SPAM !!!!!

Solución

La buena noticia es que una vez es conocido el ataque y su funcionamiento, es rápido y fácil desarrollar una defensa. En concreto, basta con que el archivo index.php compruebe primero que la variable pag no contiene una cadena que comience por "http:".

if (strtolower(substr($_POST['pag'],0,5))=='http:' or
strtolower(substr($_GET['pag'],0,5))=='http:') return;

Fijaros que se comprueba que la variable pag -sea pasada con el método POST (normalmente desde formulario) o con el método GET (normalmente embebido en una URL)- no comience por http. En caso de que así sea se ejecuta return; con lo que se detiene la ejecución del script.

Ni que decir tiene que inmediatamente incorporé esta comprobación al inicio de todos mis archivos index.php o similares de todas mis aplicaciones web ;) Y bueno, ya hace más de dos meses de eso y no he vuelto a tener problemas con ese tipo de SPAM. Espero que a más de uno le sirva!!

13 comments:

  1. hola! en que lugar del index se lo debo poner el dichoso codigo? tengo instalado en wordpress.
    exelente post!
    mi sitio: www.publicabos.com
    y el problema es que desde ahi estan enviando correos spam, tambien tengo otro sitio: www.publicabos.com.mx, pero este no lo tengo en php, y de todas maneras se estan enviando correos desde mi cuenta, hoy me llego uno vendiendome viagra desde mi sitio, pero ahi no se como esta la situacion, por que desde la .mx ni siquiera le tengo un buzon de entrada, lo tengo como opcion de reenvio para recibir en hotmail..

    ReplyDelete
  2. Hola maestro...solo una ayuda tu codigo me viene de 10z... al igual q el amigo en mi foro aparece una propaganda de Viagra... dodigo en http...
    Pero solo para salir de la duda...
    Este es tu codigo

    if (strtolower(substr($_POST['pag'],0,5))=='http:' or
    strtolower(substr($_GET['pag'],0,5))=='http:') return;

    Ahora solo para saber nada mas... q significa el 0, 5 q aparecen alli...
    desde ya gracias colega.

    ReplyDelete
  3. Hola anónimo, me alegro de que te sirviera el consejo para el mini parche de seguridad.

    En cuanto a lo que me preguntas: la función de PHP "substr" (sub-string) devuelve un trocito de una cadena (string en inglés), y normalmente necesita 3 variables:

    substr($cadena,$caracter_inicio,$numero_caracteres);

    así por ejemplo substr('hola mundo',2,4) devuelve 4 letras a partir de la segunda (teniendo en cuenta que la primera siempre es la 0, no la 1, o sea que sería a partir de la tercera); es decir, devuelve: 'la m'.

    Por esta razón, mi script lo que intenta comprobar es que los 5 primeros carácteres de la variable $pag no sean 'http:'.

    De todas formas, para ti y para los que empezáis en esto del PHP necesito recomendaros (casi casi FORZAROS) a que en estos casos consultéis el manual oficial de PHP:

    www.php.net

    en el que dan detalles y ejemplos de cada una de las funciones de este increíble lenguaje de programación. El único inconveniente puede ser el idioma, pero la mayoría está traducido al español.

    Así, por ejemplo, podrías haberte respondido a ti mismo consultando esta dirección dónde hablan de la función 'substr':

    http://www.php.net/substr

    Un saludo!
    SERGI

    ReplyDelete
  4. Mil gracias loko... la verdad... todo joyita con la explicacion... Un Saludo amigazooo... y ya nos taremos leyendo algo del Manual.... :-)

    ReplyDelete
  5. Hola de nuevo jefe.... te mando la dire de mi pagina asi veas de q se trata el tema de mi pregunta de nuevo.... crees q con esto pueda resolver ese problema www.saintsofathena.net63.net/foro.php...
    Desde ya saludos compadre...!!!

    ReplyDelete
  6. Esperando respuesta amigo...

    ReplyDelete
  7. Bueno es que lo que te pasa con los comentarios basura (spam) en tu foro no tiene nada que ver con lo que explico yo en el artículo! ;)

    Lo que tú necesitas es otra cosa, de hecho dos cosas: por una parte un filtro anti-spambots (programitas que rellenan automaticamente formularios de webs con spam) y un filtro anti-comentarios-basura (parece ser lo que tú tienes: palabras como VIAGRA con enlaces de venta).

    Aunque he visitado tu blog no sé decir qué tipo de foro estás utilizando (uno ya hecho y de uso público, o uno hecho por ti...) ni cómo los has instalado (manualmente, o con un instalador de tu servicio de hosting, etc..). Sea como sea tienes dos opciones:

    - activas y/o instalas algún módulo específico para estas cuestiones del spam que estén programadas para el foro que estás utilizando

    - o bien te programas tu mismo un "parche", es decir, te programas tú mismo unas cuantas lineas más de código para insertarlas en los archivos del foro justo en el momento antes de "aceptar los mensajes entrantes".

    Para esto último una solución muy novedosa y de la que he oido hablar bien es Akismet, que es un servicio gratuito (al menos para usos no empresariales) y que puedes usar en tu foro insertando apenas 10 lineas de código!!! Ten por seguro que detendrá tu problema con el spam.

    En este blog, hay un excelente artículo explicando pasito a pasito como utilizar Akismet en tu foro. Aprovecho para recomendarte que te suscribas a su blog... yo lo leo desde hace un año:

    http://blog.unijimpe.net/utilizar-akismet-con-php/

    Creo que esta vez sí he resuelto tus dudas ;) suerte!

    Y salud!
    SERGI

    ReplyDelete
  8. Es una pagina 100% construida por mi... inclusive el Foro. Estoy haciendo una vercion muchisimo mejor del mismo q la estaba por subir... y resulta q cuando habro mi pagina...veo todos esos SPAM. Y pense inmediatamente en solucionar eso primero antes de subirla. Desde ya mil Gracias por la ayuda maestro... pero tengo una duda con el AKISMET... Todo bien con el codigo...joya se le entiende a la perfeccion... pero en la variable $apikey de ese modulo... de donde sacaria yo se codigo??? Disculpa mi ignorancia... :-)

    ReplyDelete
  9. MIL GRACIAS MAESTRO TODO SOLUCIONADO... ENCONTRE LO Q TENIA Q HACER CON LA APIKEY...!!!! DESDE YA UN MILLON DE GRACIAS Y CUALKIER PROBLEMA SE Q ME VAS A DAR UNA MANO COMO LO HICISTE HOY. SALUDOS AMIGO!!!!

    ReplyDelete
  10. La APIKEY te la proporciona Akismet cuando te das de alta en su servicio. Yo no lo he hecho, aunque no creo que tarde en utilizar este fabuloso servicio. Pero estoy casi seguro, a partir de lo que he leído en la página de Akismet, que has de solicitar una APIKEY para cada dominio en el que vayas a utilizar su servicio.

    Otra cosa... antes de volver a preguntar leete más a fondo la documentación existente o busca en sus foros o wiki. Posiblemente encotrarás tus respuestas más rápidamente. Y tal vez, buscando algo para ti, puedas encontrar la pregunta de alguien que sabe menos que tú y que pregunta algo a lo que sí puedes responderle ;)

    Un saludo!
    SERGI

    ReplyDelete
  11. Hombre, gracias esta forma de spam nunca me había pasado, ahora tengo a que atenerme de pasar esto, te pasaste, de seguro alguna vez te lo voy a volver a agradecer, gracias por compartir con nosotros tu sapiencia.

    Saludos.

    ReplyDelete
  12. Buen dato, aunque no relaciono el envio de e-mails con solo pasar un dato a una página a menos que tu script tenga alguna función de mandar e-mails o bien hay algo que desconozco del funcionamiento del servidor. Nunca me pasó, me han pasado cosas mas raras, pero igual lo tendré en cuenta. Gracias.

    ReplyDelete