Comunidad de diseño web y desarrollo en internet online

Ayuda con seguridad: me atacaron?! PHP+MySQL

Citar            
MensajeEscrito el 22 Sep 2011 04:35 pm
Hola, bueno les cuento mi problema espero ser claro

Resulta que tengo un sitio, y una de las páginas se accede con una url parecida a esto: ...php?op=608&id=XXXX

La id=XXXX corresponde a algo asi como un articulo, una nota.
El tema es que en MySQL tengo una tabla que va guardando una fila cada vez que alguien solicita el op=608 y guarda el ID que solicitan.

Ej de tabla:
OP | 608
ID | 9886
STAMP | 16519684354
(y asi UNA fila x cada visita qe entra)

El tema es que ayer, revisando la tabla para hacer una estadisticas, encontre que habia cerca de 1000 visitas con ID's solicitadas DISTINTAS y algunas con caracteres raros y cosas asi... Osea ID's de articulos que ni siquiera existen y de hecho el codigo PHP tiene un END cuando solicitan una ID que no exista en la tabla de articulos, con lo cual no deberia contar la visita pero lo hace de todas formas.. Es raro.
Probé ingresar yo con estos ID's y no puedo, devuelve el error correspondiente y no registra la visita.

El código siempre funcionó bien, hasta ayer que encontré esto.
Ejemplos de ID's solicitadas (y que el sistema procesó):
25¼39
2337†R
1950¼
2}f ·|¸ôi˜6
2Date†R539
1FON†R402

Puede ser algun tipo de ataque?
Me explique bien?
Pueden ayudarme?

GRACIAS (estoy preocupado :( )

PD: El sitio esta alojado en Dattatec.com

Por felpuli

4 de clabLevel



 

chrome
Citar            
MensajeEscrito el 23 Sep 2011 12:21 am
tienes 1000 visitas con ids no existentes? , estas seguro de que en ningun caso, al utilizar correctamente la aplicacion, se inserta ninguna fila de ese tipo?

no se si es un ataque o no, puede haber sido algun tipo de bot pero lo que si debes hacer es filtrar la entrada, si la id solo va a ser numerica asegurate de que antes de hacer la consulta a la BD para insertarla, se compruebe que es un numero y un numero valido, puedes hacer una consulta y comprobar que la id existe.

por ejemplo puedes codificar las variables con la funcion base64_encode() y decodificarla con base64_decode() en el otro script ...


cuando se utiliza ese tipo de datos pasados por URL que van a ser empleados para consultar la base de datos, lo mejor es filtrarlos para estar seguros de que sólo vamos a recibir datos validos y que en caso de no ser asi deben ser ignorados,

puedes codificar la id y pasarla codificada por la url y luego decodificarla en el script de destino,

Por bray

65 de clabLevel



 

firefox
Citar            
MensajeEscrito el 23 Sep 2011 12:30 am
Perdon, he intentado mover una parte del texto y la he cortado por la mitad, cuando digo que

escribió:

por ejemplo puedes codificar las variables con la funcion base64_encode() y decodificarla con base64_decode() en el otro script ...


es para codificar las variables antes de pasarlas por la URL , esta frase debio aparecer al final pero al intentar cambiarla de sitio la deje arriba y no se como editar el mensaje ! jajajajaj

un saludo

Por bray

65 de clabLevel



 

firefox
Citar            
MensajeEscrito el 23 Sep 2011 12:30 pm
Mi inquietud al leer este tema es ¿por qué te has tomado la molestia de registrar las visitas de esa manera cuando el servidor web ya lo hace por sí mismo?. Basta con que te descargues el archivo access.log y lo proceses con alguno de docenas de programas que lo hacen ;).

Por DriverOp

Claber

2510 de clabLevel



 

opera
Citar            
MensajeEscrito el 23 Sep 2011 02:36 pm
Muchas gracias Bray y DriverOp por las respuestas..
Para que se den una idea, esa pagina esta diagramada asi:

INDEX (que tiene todos los cases llamados con el ?op=XXXX) (Este index.php tiene el include de conexion a MySQL, entonces solo lo llama una vez x pag)
--PAG DEL ARTICULO (que la llama con el ?op=XXXX&id=YYYY)
----INCLUDE (que llama al archivo (qe esta en otro directorio, y que si se ejecuta fuera del index.php no puede conectar a la BD) que guarda la información de visitas.

El tema es que la pag del artículo, empieza con este codigo:

Código PHP :

$existe_articulo=mysql_num_rows($consultasql);
if($existe_articulo<1){
   $log_descripcion="Error: $op / 07 | Los datos no coinciden "; //Este texto se guarda en una tabla de logs de error en MySQL
   include_once("logs/error_log.php");
   exit("ERROR $op.07 - Los datos no coinciden - El error ha sido registrado y será verificado -");
}


No veo el error de que se puedan contar las visitas (y otros scripts mas que se ejecutan) si en la 5 linea ya está el EXIT y no debería ejecutar mas nada... No se.
Tampoco puede llamar aislado al script de las estadisticas porque no podria conectar a la BD...
Qizas sea un error mio y no lo sepa :) (si es asi, perdon jaja)

DriverOp escribió:

Mi inquietud al leer este tema es ¿por qué te has tomado la molestia de registrar las visitas de esa manera cuando el servidor web ya lo hace por sí mismo?


Es que necesito que los "dueños" de los artículos tengan estadísticas en tiempo real.

MUCHAS GRACIAS!!!

Por felpuli

4 de clabLevel



 

chrome
Citar            
MensajeEscrito el 23 Sep 2011 03:28 pm
La cuestion es que tienes un problema con la fiabilidad de los datos de la base de datos y se te insertan datos no validos, debes comprobar que los datos son validos antes de insertarlos. Para resolver ese fallo el código que necesitaríamos seria el que hace la consulta de insercion en la BD para comprobar los accesos de los usuarios.
Este codigo que has puesto solo nos dice que si no hay articulos, salga del script, pero no nos dice como comprueba si hay articulos, no nos dice si tienes cuidado de prevenir la inyeccion de codigo sql... esas suponiendo que todas las entradas de los usuarios van a ser honestas y ... eso es lo primero que tienes que olvidar, tienes que pensar que haran los usuarios deshonestos.

lo que debes hacer es, comprobar el identificador de articulo antes de introducirlo, O bien declarandolo como clave externa en la propia tabla que guardas las visitas, o bien haciendo una consulta a la BD de los articulos y comprobando que ese identificador existe,

no creo que sea un error de sintaxis (que puede serlo) creo que es mas bien un problema de integridad de datos que no compruebas, siempre se debe comprobar la integridad de los datos antes de insertar o eliminar de una BD porque los usuarios inexpertos o los maliciosos siempre te pueden sorprender.

Por bray

65 de clabLevel



 

firefox
Citar            
MensajeEscrito el 23 Sep 2011 05:03 pm

Código PHP :

$consultasql=mysql_query("SELECT * FROM l_articulos WHERE id='$id' && estado='1' && habilitado='1' LIMIT 0,1");

Y después sigue con el código que ya habia puesto...

Código PHP :

$existe_articulo=mysql_num_rows($consultasql); 
if($existe_articulo<1){ 
   $log_descripcion="Error: $op / 07 | Los datos no coinciden "; //Este texto se guarda en una tabla de logs de error en MySQL 
   include_once("logs/error_log.php"); 
   exit("ERROR $op.07 - Los datos no coinciden - El error ha sido registrado y será verificado -"); 
} 


En la tabla l_articulos, la columna ID es INT(11) clave primaria auto_increment.

Estas líneas de código no deberían frenar TODO el script que le siga (incluyendo al script que guarda las estadisticas), al intentar poner un ID qe no exista en la tabla?

Porque se supone que en la tabla los ID solo son INT, asíque si llamas a una ID que no sea un entero no debería funcionar.. Y si es un entero y no esta en tabla tampoco.

Estoy molestando mucho?
Perdon!! Pero es qe no entiendo juro qe no entiendo :(

Por felpuli

4 de clabLevel



 

chrome
Citar            
MensajeEscrito el 23 Sep 2011 05:30 pm
Pero sigues presunponiendo que el id que te va a llegar es valido
te voy a poner un ejemplo sabes lo que es el sql injection ???

pon la url de un articulo en el navegador y tras el campo id escribe esto 'OR '1' = '1 y comprueba lo que pasa, si esto funciona ya tienes tu respuesta.

Estas suponiendo que el id que llega a la consulta es un numero y que por lo tanto mysql lo va a poder comprobar como tal pero que pasa si no es un numero? o si es una sentencia como la que te he puesto arriba??? debes filtrar los datos

Por bray

65 de clabLevel



 

firefox
Citar            
MensajeEscrito el 23 Sep 2011 07:44 pm
Aaaaaaaaaaaaaaaaahhhhhhhh!!!
Ya entendiii
Perdoooooon! Jajaja lo mas triste es que ya me paso una vez!
Como lo soluciono? :$

Por felpuli

4 de clabLevel



 

chrome
Citar            
MensajeEscrito el 24 Sep 2011 03:03 pm

Por DriverOp

Claber

2510 de clabLevel



 

opera
Citar            
MensajeEscrito el 27 Sep 2011 02:23 pm
Muchas gracias a todos por la respuesta..
Pero tengo una duda: ¿Con esto no soluciono la SQL Injection o si?.
O sea, lo soluciono en parte.. pero habia una funcion que previene todo el injection, o estoy confundido? :(

Gracias a todoooos!!

Por felpuli

4 de clabLevel



 

chrome
Citar            
MensajeEscrito el 27 Sep 2011 03:55 pm
Prevenir la inyeccion de codigo sql puedes utilizar dos funciones, la funcion trim() y la funcion addslashes antes de insertar valores en la bd. Estas funciones son utiles cuando los datos que se van a introducir son susceptibles de ser manipulados por los usuarios. como por ejemplo cuando lo pasas por URL. Para el problema que has planteado en este tema, con comprobar si son numericos y que estan en la bd ya evitarias pero siquieres asegurarte puedes usar

addslashes(trim($valor_a_insertar));

para usar las funciones addslashes o stripslashes tienes que asegurarte de que el servidor tiene desactivadas las magic_quotes , de hecho yo te recomiendo que las desactives en todos tus trabajos porque a parte de desaparecer en php6, dan mas quebraderos de cabeza de los que solucionan. Bueno igual esto es liarte un poco, si buscas tutoriales por la web sobre como evitar el sql injection veras como se utilizan estas funciones con mas detalle.

ademas te recomendaría que mirases también lo de las magic_quotes()

por si te interesa, tambien existen otros tipos de inyección de código, que es conveniente evitar, no sólo la sql. los tipos mas comunes suelen ser:

- inyeccion javascript ó php : en campos o areas de texto.
- mail inyection: cuando se usa la funcion mail para formularios de contacto


a lo mejor es liarte un poco mas , pero siempre esta bien saberlo y poner un mínimo de prevención es sencillo en ambos casos, la prevencion total no existe, pero se puede poner lo mas complicado posible.
un saludo.

Por bray

65 de clabLevel



 

firefox
Citar            
MensajeEscrito el 29 Sep 2011 06:49 pm
Muchisimas gracias voy a ir aplicando todas las cosas que me dijeron jaja pero me va a llevar tiempo...
Tengo una ULTIMISISISISISSISIMA pregunta.. Alguno sabe que tan seguro es el sistema de login ese de navegador.. como eplicar.. el que sale la ventanita y pide usuario y contraseña.. como cuando uno intenta entrar a un puerto que esta protegido, o a un ftp .. ese estilo.. son seguros?

Por felpuli

4 de clabLevel



 

chrome
Citar            
MensajeEscrito el 29 Sep 2011 09:48 pm
El problema de ese sistema de autenticacion es que es generico, es decir a todo el mundo le sale la misma ventanita y no depende del diseño de la pagina , asi que es posible que alguien redireccione al usuario a otra pagina , simule la ventana y consiga el nombre de usuario y contraseña que se introduce. Por otro lado copiar el diseño de una pagina HTML-CSS es algo mas complejo sobre todo legalmente.

si quieres aumentar la seguridad de tu sitio te recomiendo una autenticacion por formulario y la contraseña que se introduzca mediante un teclado virtual . Pero tambien hay que tener en cuenta la importancia de la informacion si la informacion que se almacena no es demasiado importante, tampoco es necesaria una seguridad muy rebuscada.

un saludo.

Por bray

65 de clabLevel



 

firefox
Citar            
MensajeEscrito el 18 Oct 2011 05:08 pm
Muchas gracias a todos.
Encontré esta función que probablemente me ayude bastante!
mysql_real_escape_string

Por felpuli

4 de clabLevel



 

chrome

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.