lunes, 21 de junio de 2010

Inyección SQL




La inyección SQL es un agujero de seguridad en la informática que se puede producir al ejecutar una sentencia en una base datos con datos entrados por usuarios mal intencionados o por error en algunos casos. La inyección se produce cuando el programador no filtra de forma correcta los datos para evitar la posible inyección.
El nombre de inyección viene dado por la forma en que se introduce el código mal intencionado en el código correcto.
El ejemplo clásico es una sentencia para verificar una autenticación de usuario.
Tenemos en la base de datos de nuestro sistema una tabla llamada usuario, que contiene el nombre del usuario, el correo electrónico, la contraseña, entre otros datos.
Para verificar los datos de un usuario, se utilizaría la siguiente sentencia SQL:



Select count(*) from usuario where nombre_usuario = 'dato_usuario' and contrasena = 'dato_pass'


Lo que se hace en esta sentencia es contar los usuarios que tengan el mismo nombre de usuario entrado (dato_usuario) y la contraseña entrada (dato_pass). Normalmente un resultado positivo daría como resultado una cantidad igual 1 si los datos coinciden y 0 si el usuario o la contraseña entrada están mal.
Por ejemplo:


Select count(*) from usuario where nombre_usuario = 'pepe' and contrasena = '12345'



Sin embargo si el programador no valida que el valor: dato_usuario y : dato_pass , no contengan datos maliciosos podría ocurrir lo siguiente:

Select count(*) from usuario where nombre_usuario = 'pepe' and contrasena = ' cualquier_cosa' or 'h' = 'h '

En este caso sea cual sea el nombre de usuario que se entre el resultado sería una cantidad mayor que 0 y por lo tanto lograría tener acceso sin la contraseña correcta al un servicio que se esté programando. La razón es que en vez de entrar una contraseña, se inyectó un código malicioso al código SQL original para alterar su funcionamiento correcto.

Fíjense que se altera el funcionamiento porque se introdujo: cualquier_cosa' or 'h' = 'h en vez de una contraseña , si lo dividimos por partes veremos que cualquier_cosa' cierra la contraseña y luego viene un operador OR lo que implica que si después del OR la operación da como resultado Verdadero toda la operación es verdadera ya que (false OR true) = true. Después del OR viene 'h'='h que se cierra con la última comilla, quedando 'h'='h' y es evidente que 'h' es igual 'h'.

Este ejemplo no es de los más trágicos pues igualmente se pueden ejecutar sentencia que borren todos los registros de la base de datos, lo cual podría provocar un serio problema en cualquier sistema.


¿Cómo evitar las Inyecciones SQL?

Evidentemente para evitar este problema simplemente hay que filtrar los datos externos que entremos en la sentencia SQL. En dependencia del sistema gestor de base datos y el lenguaje de programación existen muchas formas de evitar el problema.


Si usamos PHP - MYSQL

Si usamos el gestor de bases de datos lo que debemos hacer es eliminar las comillas. Explicaré a continuación como evitar el ataque usando lenguaje de programación PHP .


  1. No permitir comillas en casos de datos como un nombre de usuario, el cual solo debería aceptar caracteres alfanuméricos. Esto sin duda evitaría este problema sin mayores contratiempos con un simple filtro.

  2. Escapar todas las comillas de un texto determinado. Escapar no es más que colocar o anteponer el carácter “\” antes de poner una comilla, el carácter “\” indica que luego viene un carácter especial, evitando que este carácter tenga una interpretación errónea. Si sabemos en MYSQL el carácter Comilla tiene un significado especial , evitamos este significado al anteponer: “\”. Usted podría programar su propia función para realizar este filtro , sin embargo ya existen funciones en PHP que ejecutan esta tarea de manera eficiente. Lo ideal es usar la función mysql_real_escape_string.

  3. Entonces el ejmplo inicial quedaría de la siquiente forma:


    $pass = mysql_real_escape_string($pass);

    $query = “Select count(*) from usuario where nombre_usuario = ‘pepe’ and contrasena = ‘$pass’ “;


  4. La función mysql_real_escape_string está disponible en versiones superiores de PHP , no en las versiones antiguas 3 y 4. Por lo tanto es posible que tenga que usar otras formas de escapar los datos. Por ejemplo:


  5. $valor = str_replace(“’”, “\’” ,$valor); // lo que hacemos es reemplazar todas las comillas simples por \’.


  6. La función addslashes , también puede ser usada directamente para adicionar barra invertida a los caracteres comilla simple ('), comilla doble ("), barra invertida (\) y valor NULL. La función contraria a esta es stripslashes , la cual elimina las barras invertidas dejando la cadena como mismo estaba al inicio.


  7. Magic quotes , es una forma de evitar inyección SQL en PHP , la cual no recomiendo yo como programador ni prácticamente nadie en ningún artículo de los que he leído. Esta es una opción que puede habilitarse en la configuración de PHP (magic_quotes_gpc=on) y que en versiones antiguas venía habilitado por defecto. Lo que hace esta opción es aplicar el escape de las comillas en todos los datos que vienen por las variables: $_GET, $_REQUEST, $_POST and $_COOKIE de forma automática. Sin duda fue una solución muy exagerada y que trajo consigo que fue peor el remedio que la enfermedad. Si me preguntan el por qué:

    - Hay muchos muchísimos datos que usamos en nuestras aplicaciones que no intentan poner una inyección SQL. Por ejemplo cuando almacena código HTML , el cual contiene comillas que no necesariamente traen problemas en la base de datos.

    - Esto no resuelve ningún problema en gestores de base datos que tienen otras vulnerabilidades que no son precisamente las comillas.



    Nota: Es muy importante tener presente que si tenemos en uso esta opción a su conveniencia como programador, debe tener cuidado de no usar las funciones addslashes , ya que entonces obtendría una cadena con doble escape. La forma de saber esto de forma automática e independiente de la configuración PHP que tenga un servidor u otro es consultando la función get_magic_quotes_gpc() , si da como resultado 1 es que Magic quotes está activada.



    Luego si queremos recuperar estos valores de la base de datos y que se restablezcan a su estado original con las comillas podemos usar la ya mencionada función: stripslashes , que como su nombre lo indica elimina las barras invertidas.





No dude nunca en detenerse y analizar en su proyecto que método de seguridad va usar para evitar este tipo de ataque. La Inyección SQL es un ataque prevenible y que a veces se olvida tener en cuenta.

Moisés Soft , le responderá cualquier duda que tenga acerca de Inyección SQL. No dude en contactarnos

jueves, 10 de junio de 2010

SEO NOFOLLOW NOINDEX

En un articulo anterior ya explicamos que es SEO y la importancia que tiene para el existo de una página web en Internet.

En esta ocasión explicaré, la importancia que tienen las palabras NOFOLLOW NOINDEX usadas en distintas etiquetas de nuestros sitios web.

Cuando usted emprende la ardua tarea de posicionar su web en los buscadores de Internet ,la primera tarea es identificar las palabras o conjuntos de palabras que se relacionan con su web y que son las más usadas por los usuarios para buscar un servicio como el que usted brinda. Una vez que usted identifique esas palabras comenzara a usarlas de muchas maneras en su web , logrando que la densidad de las mismas sea alta. Pero de seguro tendrá contenidos no importantes, por ejemplo una de las páginas que usted de seguro no esta muy interesado que aparezca en Google, es la de los términos de uso , Login , Registro de usuario, entre muchas otras.
La respuesta está en el título de este artículo. El uso de las palabras NOFOLLOW NOINDEX , permite evitar perder la densidad de las palabras realmente importantes y los link realmente importantes.

¿Cómo hacer que una página no sea indexada por Google?
Haciendo uso de la etiqueta Meta, que debemos colocar en el Head del documento HTML de nuestra página colocaríamos lo siguiente:
<meta name=”robots” content=”noindex, nofollow” />

¿Cómo evitar que un vínculo a una página no sea seguido por Google?
Tan sencillo como escribir lo siguiente:
<a rel=”nofollow” href=”mi_vinculo_no_deseado.html”> Mi link </a>

¿Cómo hacer que un vínculo a una página no sea indexado ni seguido por Google?
Si usted además de no desear que Google rastree el link , tampoco desea que tenga en cuenta el texto del link coloca el atributo rel , indicando “nofollow, noindex”: que quiere decir no seguir , no indexar.
<a rel=”nofollow, noindex” href=”mi_vinculo_no_deseado.html”> Mi link no indexado, no seguido</a>

¿Cómo hacer que un vínculo a una página no sea indexado pero si seguido por Google?
<a rel=” noindex” href=”mi_vinculo_seguido.html”> Texto no indexado</a>

¿Cuándo usar este artificio?
- Cuando no deseamos que una página de nuestro sitio sea indexada: Etiqueta Meta
- Cuando el texto del link contiene una palabra que no deseamos que sea tomada en cuenta. Etiqueta A con rel=’NOINDEX’
- Cuando tenemos un link que no deseamos sea seguido por Google: Etiqueta A con rel=’NOFOLLOW’
- Cuando tenemos un link que no deseamos que sea indexado ni seguido por Google: Etiqueta A con rel=’NOFOLLOW, NOINDEX’

Consejos útiles:

- Usa esto atributos en todos los links salientes de tu página, por ejemplo en los mensajes de opiniones o comentarios escritos por usuarios de tu sitio web.
- En la paginas de términos de uso, registros de usuarios , login , FAQ, en otros. Aunque estas páginas no son un regla sin excepción.
- En los link que tengan palabras fijas como por ejemplo : “Ver contenido” ,”Vista previa”, “Aceptar” , entre otros tantos que se usan hoy en las web y que cuando se repiten muchas veces roban protagonismo por su densidad. Para estos link es recomendado usar NOINDEX , para evitar que Google tenga en cuenta los textos , y siga los links.