## SQLI El SQl injection es una vulnerabilidad que puede tener cualquier aplicación, no solo las webs.consistente en "romper" una instrucción SQL que genera la aplicación y por el cual podemos acceder a información de una base de datos que a priori no deberíamos poder acceder. Un ejemplo muy simple, supongamos que una aplicación ejecuta la siguiente instrucción SQL: select nombre,apellidos from empleados where id='1′; ​Esto nos devolvería el nombre y apellidos de un empleado cuyo identificador "id" sea '1' Imaginemos que ese '1' lo hemos introducido nosotros en un campo de nuestra aplicación, ¿qué sucedería si introdujésemos en ese campo en lugar de un 1 esta secuencia 1′ or '1'='1? Que entonces nuestra aplicación (si es vulnerable) ejecutaría: select nombre,apellidos from empleados where id='1′ or '1'='1'; Un atacante también puede comentar el resto de la declaración SQL para controlar aún más la ejecución de la consulta SQL. ```sql= -- MySQL, MSSQL, Oracle, PostgreSQL, SQLite ' OR '1'='1' -- ' OR '1'='1' /* -- MySQL ' OR '1'='1' # -- Access (using null characters) ' OR '1'='1' %00 ' OR '1'='1' %16 ``` Una vez que se ejecuta la consulta, el resultado se devuelve a la aplicación para su procesamiento, lo que da como resultado una omisión de autenticación. ![](https://assets.website-files.com/5ff66329429d880392f6cba2/608958ea27293628afb3b58b_SQL%20injection%20work.jpg) ## Tipos de SQLI El tipo de ataque a realizar depende fundamentalmente de cómo sea la query sobre la que se está realizando y de lo que devuelve la página al intentar introducir una SQLi: - Staqued Queries: Consiste en colocar nuevas consultas al final de la consulta inyectable. Es el mejor método puesto que es el que más cosas permite sacar de la base de datos, por lo que es la mejor opción si está disponible. - Union query based: Recupera datos añadiendo una query a la original mediante el comando UNION. Necesitas poder ver los resultados de la query en la página web para que funcione. - Error based: Manipula los mensajes de error para mostrar en ellos los datos de la base de datos. - Inline queries: Este tipo de ataque consiste en embeber una query en otra (SELECT(SELECT…)…). - Boolean blind: Consiste en hacer queries de tipo true/false y según los cambios en las respuestas, ir descubriendo información sobre la base de datos. Por ejemplo, si inyectamos ‘ or ‘1’ = ‘1’ y nos devuelve un mensaje de error A, e inyectamos ‘ or ‘1’ = ‘2’ y nos devuelve otro mensaje de error B que es distinto del mensaje de error A, podemos inyectar ahora ‘ or current_user = ‘carlos’. Si nos devuelve el mensaje de error A, el usuario es carlos, en caso de que devuelva el mensaje de error - Time based blind: La lógica es la misma que en el caso anterior, pero en vez de contrastar entre distintas respuestas, comprueba distintos tiempos de respuesta. Por ejemplo, para averiguar si el usuario es carlos, inyectaríamos ‘ or (current_user = ‘carlos’ and WAITFOR DELAY ‘0:0:10’). Si el usuario es carlos, la consulta tardará 10 segundos más de lo habitual en ejecutarse, si no lo es, el tiempo de respuesta será el habitual en esa web. ## Como Prevenir Tanto si es una aplicación web como de escritorio, tenemos que tener cuidado con los mensajes de error, no debemos dar más información de la que se deba. Si en nuestro mensaje de error mostramos: "Error en la sentencia SQL generada sobre la tabla EMPLEADOS — ORA-01756: quoted string not properly terminated" Con este mensaje se deja indicado que: - Se usa una base de datos Oracle. - Existe una tabla EMPLEADOS. - La sentencia ejecutada retorna un error con el entrecomillado (posible vulnerabilidad de SQL injection) Así que ojo con los mensajes que ponemos, pueden facilitarnos la vida en algunos aspectos, pero nos la pueden complicar en otros. "Escapar" los caracteres especiales, es decir añadir una barra \ delante de ellos para delimitarlos y así que no se "rompa" tan fácilmente la sentencia SQL. Comprobar los tipos de datos que se van a consultar, si el campo es un numérico, ¿porqué permitir que se puedan introducir otros caracteres? Así que dependiendo del lenguaje de la aplicación, hacer todas las validaciones que consideréis oportunas. Verificar los privilegios de los usuarios, si un usuario únicamente debe hacer consultas sobre unas tablas, no se le debe permitir el acceso al resto ni la ejecución de sentencias SQL que no deba.