Coders Conquer Security: Compartir y aprender - Inyección SQL
En términos sencillos, SQL (o Structured Query Language) es el lenguaje utilizado para comunicarse con las bases de datos relacionales; es el lenguaje de consulta que utilizan los desarrolladores, los administradores de bases de datos y las aplicaciones para gestionar las enormes cantidades de datos que se generan cada día.
Nuestros datos se están convirtiendo rápidamente en una de las mercancías más valiosas del mundo... y cuando algo es valioso, los malos querrán poner sus manos en él para su beneficio.
Los atacantes están utilizando la inyección SQL, una de las vulnerabilidades de datos más antiguas(¡desde 1998!) y más molestas que existen, para robar y cambiar la información sensible disponible en millones de bases de datos de todo el mundo. Es insidiosa, y los desarrolladores deben entender la inyección SQL (así como la forma de defenderse contra ella) si queremos mantener nuestros datos a salvo.
Para ello, discutiremos tres aspectos clave de la inyección SQL:
- Cómo funciona
- Por qué es tan peligroso
- Cómo defenderse
Comprender la Inyección SQL
La inyección SQL se puede entender con una palabra: contexto.
Dentro de una aplicación, existen dos contextos: uno para los datos y otro para el código. El contexto de código indica al ordenador qué debe ejecutar y lo separa de los datos que debe procesar.
La inyección SQL se produce cuando un atacante introduce datos que son tratados erróneamente como código por el intérprete de SQL.
Un ejemplo es un campo de entrada en un sitio web, donde un atacante introduce ''' OR 1=1" y se añade al final de una consulta SQL. Cuando esta consulta se ejecuta, devuelve "true" para cada fila de la base de datos. Esto significa que se devolverán todos los registros de la tabla consultada.
Las implicaciones de la inyección SQL pueden ser catastróficas. Si esto ocurre en una página de inicio de sesión, podría devolver todos los registros de los usuarios, incluyendo posiblemente los nombres de usuario y las contraseñas. Si una simple consulta para sacar datos tiene éxito, las consultas para cambiar los datos también lo harían.
Echemos un vistazo a un código vulnerable para que pueda ver cómo es una vulnerabilidad de inyección SQL en carne y hueso.
Mira este código:
String query = "SELECT account balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
Statement statement = connection.createStatement( ... );
ResultSet results = statement.executeQuery( query );
}
El código aquí simplemente añade la información de los parámetros del cliente al final de la consulta SQL sin ninguna validación. Cuando esto ocurre, un atacante puede introducir código en un campo de entrada o en los parámetros de la URL y se ejecutará.
La clave no es que los atacantes sólo puedan añadir ''' OR 1=1" a cada consulta SELECT, sino que un atacante puede manipular cualquier tipo de consulta SQL (INSERT, UPDATE, DELETE, DROP, etc.) y ampliarla con cualquier cosa que soporte la base de datos. Hay grandes recursos y herramientas disponibles en el dominio público que muestran lo que es posible.
Pronto aprenderemos a corregir este problema. En primer lugar, vamos a entender cuánto daño se puede hacer.
Por qué la inyección SQL es tan peligrosa
Estos son sólo tres ejemplos de infracciones causadas por la inyección SQL:
- El sitio web de la Junta Electoral de Illinois fue violado debido a vulnerabilidades de inyección SQL. Los atacantes robaron los datos personales de 200.000 ciudadanos estadounidenses. Por la naturaleza de la vulnerabilidad encontrada, los atacantes podrían haber modificado también los datos, aunque no lo hicieron.
- Hetzner, una empresa sudafricana de alojamiento de sitios web, sufrió un ataque que afectó a 40.000 registros de clientes. Una vulnerabilidad de inyección SQL condujo al posible robo de todos los registros de clientes de su base de datos.
- Un proveedor de servicios financieros católicos en Minnesota, Estados Unidos, fue vulnerado mediante inyección SQL. Se robaron los datos de las cuentas, incluidos los números de cuenta, de casi 130.000 clientes.
Los datos sensibles pueden utilizarse para hacerse con cuentas, restablecer contraseñas, robar dinero o cometer fraudes.
Incluso la información que no se considera sensible o de identificación personal puede utilizarse para otros ataques. La información de la dirección o los últimos cuatro dígitos de su número de identificación gubernamental pueden ser utilizados para hacerse pasar por usted ante las empresas, o para restablecer su contraseña.
Cuando un ataque tiene éxito, los clientes pueden perder la confianza en la empresa. Recuperarse de los daños en los sistemas o de las multas reglamentarias puede costar millones de dólares.
Pero no tiene por qué acabar así para ti.
Derrotar la inyección SQL
La inyección SQL puede ser derrotada etiquetando claramente las partes de su aplicación, para que el ordenador sepa si una determinada parte son datos o código a ejecutar. Esto puede hacerse utilizando consultas parametrizadas.
Cuando las consultas SQL utilizan parámetros, el intérprete SQL utilizará el parámetro sólo como datos. No lo ejecuta como código.
Por ejemplo, un ataque como ''' OR 1=1" no funcionará. La base de datos buscará la cadena "OR 1=1" y no la encontrará en la base de datos. Simplemente se encogerá de hombros y dirá: "Lo siento, no puedo encontrarlo".
Un ejemplo de consulta parametrizada en Java tiene el siguiente aspecto:
La mayoría de los marcos de desarrollo proporcionan defensas integradas contra la inyección SQL.
Los mapeadores relacionales de objetos (ORM), como Entity Framework en la familia .NET, parametrizan las consultas por defecto. Esto se encargará de la inyección SQL sin ningún esfuerzo por su parte.
Sin embargo, debe saber cómo funciona su ORM específico. Por ejemplo, Hibernate, un ORM muy popular en el mundo de Java, puede ser vulnerable a la inyección SQL si se utiliza de forma incorrecta.
Parametrizar las consultas es la primera y mejor defensa, pero hay otras. Los procedimientos almacenados también admiten parámetros SQL y pueden utilizarse para evitar la inyección SQL. Tenga en cuenta que los procedimientos almacenados también deben ser construidos correctamente para que esto funcione.
// This should REALLY be validated too
String custname = request.getParameter("customerName");
// perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.preparedStatement( query );
pstmt.setString(1, custname);
ResultSet results = pstmt.executeQuery( );
Valide y sanee siempre sus entradas. Dado que algunos caracteres, como "OR 1=1", no van a ser introducidos por un usuario legítimo de tu aplicación, no hay necesidad de permitirlos. Puedes mostrar un mensaje de error al usuario o eliminarlos de tu entrada antes de procesarla.
Al decir esto, no dependas sólo de la validación y la higienización para protegerte. Los humanos inteligentes han encontrado formas de evitarlo. Son buenas estrategias de Defensa en Profundidad (DiD), pero la parametrización es la forma segura de cubrir todas las bases.
Otra buena estrategia de DiD es utilizar el "mínimo privilegio" dentro de la base de datos y la lista blanca de entrada. Aplicar el privilegio mínimo significa que su aplicación no tiene un poder ilimitado dentro de la base de datos. Si un atacante consigue acceder, el daño que puede hacer es limitado.
OWASP tiene una gran hoja de trucos de inyección SQL disponible para mostrar cómo manejar esta vulnerabilidad en varios lenguajes y plataformas... pero si quieres ir más allá, puedes jugar un desafío de inyección SQL en tu lenguaje preferido en nuestra plataforma ahora mismo; aquí hay algunos de los más populares para empezar:
Inyección SQL en Python Django
Comienza el viaje
Has hecho un gran progreso en la comprensión de la inyección SQL, y los pasos necesarios para solucionarlo. ¡Impresionante!
Ya hemos hablado de cómo se produce la inyección SQL; por lo general, un atacante utiliza la entrada para controlar las consultas de su base de datos para sus propios fines nefastos.
También hemos visto los daños causados por la explotación de las vulnerabilidades de inyección SQL: Las cuentas pueden verse comprometidas y se pierden millones de dólares... una pesadilla, y muy cara.
Hemos visto cómo prevenir la inyección SQL:
- Parametrización de las consultas
- Uso de mapeadores relacionales de objetos y procedimientos almacenados
- Validación y lista blanca de entradas de usuarios
Ahora, depende de ti. La práctica es la mejor manera de seguir aprendiendo y dominando el idioma, así que ¿por qué no echas un vistazo a nuestros Recursos de aprendizaje sobre la inyección de SQL, y luego pruebe nuestra demostración gratuita de la plataforma? Estarás en camino de convertirte en un Secure Code Warrior.
Los atacantes están utilizando la inyección SQL - una de las vulnerabilidades de datos más antiguas (¡desde 1998!) y más molestas que existen- para robar y cambiar la información sensible disponible en millones de bases de datos de todo el mundo.
Jaap Karan Singh es un evangelista de la codificación segura, jefe Singh y cofundador de Secure Code Warrior.
Secure Code Warrior está a disposición de su organización para ayudarle a proteger el código a lo largo de todo el ciclo de vida de desarrollo de software y crear una cultura en la que la ciberseguridad sea una prioridad. Tanto si es director de AppSec, desarrollador, CISO o cualquier persona implicada en la seguridad, podemos ayudar a su organización a reducir los riesgos asociados a un código inseguro.
Reservar una demostraciónJaap Karan Singh es un evangelista de la codificación segura, jefe Singh y cofundador de Secure Code Warrior.
En términos sencillos, SQL (o Structured Query Language) es el lenguaje utilizado para comunicarse con las bases de datos relacionales; es el lenguaje de consulta que utilizan los desarrolladores, los administradores de bases de datos y las aplicaciones para gestionar las enormes cantidades de datos que se generan cada día.
Nuestros datos se están convirtiendo rápidamente en una de las mercancías más valiosas del mundo... y cuando algo es valioso, los malos querrán poner sus manos en él para su beneficio.
Los atacantes están utilizando la inyección SQL, una de las vulnerabilidades de datos más antiguas(¡desde 1998!) y más molestas que existen, para robar y cambiar la información sensible disponible en millones de bases de datos de todo el mundo. Es insidiosa, y los desarrolladores deben entender la inyección SQL (así como la forma de defenderse contra ella) si queremos mantener nuestros datos a salvo.
Para ello, discutiremos tres aspectos clave de la inyección SQL:
- Cómo funciona
- Por qué es tan peligroso
- Cómo defenderse
Comprender la Inyección SQL
La inyección SQL se puede entender con una palabra: contexto.
Dentro de una aplicación, existen dos contextos: uno para los datos y otro para el código. El contexto de código indica al ordenador qué debe ejecutar y lo separa de los datos que debe procesar.
La inyección SQL se produce cuando un atacante introduce datos que son tratados erróneamente como código por el intérprete de SQL.
Un ejemplo es un campo de entrada en un sitio web, donde un atacante introduce ''' OR 1=1" y se añade al final de una consulta SQL. Cuando esta consulta se ejecuta, devuelve "true" para cada fila de la base de datos. Esto significa que se devolverán todos los registros de la tabla consultada.
Las implicaciones de la inyección SQL pueden ser catastróficas. Si esto ocurre en una página de inicio de sesión, podría devolver todos los registros de los usuarios, incluyendo posiblemente los nombres de usuario y las contraseñas. Si una simple consulta para sacar datos tiene éxito, las consultas para cambiar los datos también lo harían.
Echemos un vistazo a un código vulnerable para que pueda ver cómo es una vulnerabilidad de inyección SQL en carne y hueso.
Mira este código:
String query = "SELECT account balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
Statement statement = connection.createStatement( ... );
ResultSet results = statement.executeQuery( query );
}
El código aquí simplemente añade la información de los parámetros del cliente al final de la consulta SQL sin ninguna validación. Cuando esto ocurre, un atacante puede introducir código en un campo de entrada o en los parámetros de la URL y se ejecutará.
La clave no es que los atacantes sólo puedan añadir ''' OR 1=1" a cada consulta SELECT, sino que un atacante puede manipular cualquier tipo de consulta SQL (INSERT, UPDATE, DELETE, DROP, etc.) y ampliarla con cualquier cosa que soporte la base de datos. Hay grandes recursos y herramientas disponibles en el dominio público que muestran lo que es posible.
Pronto aprenderemos a corregir este problema. En primer lugar, vamos a entender cuánto daño se puede hacer.
Por qué la inyección SQL es tan peligrosa
Estos son sólo tres ejemplos de infracciones causadas por la inyección SQL:
- El sitio web de la Junta Electoral de Illinois fue violado debido a vulnerabilidades de inyección SQL. Los atacantes robaron los datos personales de 200.000 ciudadanos estadounidenses. Por la naturaleza de la vulnerabilidad encontrada, los atacantes podrían haber modificado también los datos, aunque no lo hicieron.
- Hetzner, una empresa sudafricana de alojamiento de sitios web, sufrió un ataque que afectó a 40.000 registros de clientes. Una vulnerabilidad de inyección SQL condujo al posible robo de todos los registros de clientes de su base de datos.
- Un proveedor de servicios financieros católicos en Minnesota, Estados Unidos, fue vulnerado mediante inyección SQL. Se robaron los datos de las cuentas, incluidos los números de cuenta, de casi 130.000 clientes.
Los datos sensibles pueden utilizarse para hacerse con cuentas, restablecer contraseñas, robar dinero o cometer fraudes.
Incluso la información que no se considera sensible o de identificación personal puede utilizarse para otros ataques. La información de la dirección o los últimos cuatro dígitos de su número de identificación gubernamental pueden ser utilizados para hacerse pasar por usted ante las empresas, o para restablecer su contraseña.
Cuando un ataque tiene éxito, los clientes pueden perder la confianza en la empresa. Recuperarse de los daños en los sistemas o de las multas reglamentarias puede costar millones de dólares.
Pero no tiene por qué acabar así para ti.
Derrotar la inyección SQL
La inyección SQL puede ser derrotada etiquetando claramente las partes de su aplicación, para que el ordenador sepa si una determinada parte son datos o código a ejecutar. Esto puede hacerse utilizando consultas parametrizadas.
Cuando las consultas SQL utilizan parámetros, el intérprete SQL utilizará el parámetro sólo como datos. No lo ejecuta como código.
Por ejemplo, un ataque como ''' OR 1=1" no funcionará. La base de datos buscará la cadena "OR 1=1" y no la encontrará en la base de datos. Simplemente se encogerá de hombros y dirá: "Lo siento, no puedo encontrarlo".
Un ejemplo de consulta parametrizada en Java tiene el siguiente aspecto:
La mayoría de los marcos de desarrollo proporcionan defensas integradas contra la inyección SQL.
Los mapeadores relacionales de objetos (ORM), como Entity Framework en la familia .NET, parametrizan las consultas por defecto. Esto se encargará de la inyección SQL sin ningún esfuerzo por su parte.
Sin embargo, debe saber cómo funciona su ORM específico. Por ejemplo, Hibernate, un ORM muy popular en el mundo de Java, puede ser vulnerable a la inyección SQL si se utiliza de forma incorrecta.
Parametrizar las consultas es la primera y mejor defensa, pero hay otras. Los procedimientos almacenados también admiten parámetros SQL y pueden utilizarse para evitar la inyección SQL. Tenga en cuenta que los procedimientos almacenados también deben ser construidos correctamente para que esto funcione.
// This should REALLY be validated too
String custname = request.getParameter("customerName");
// perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.preparedStatement( query );
pstmt.setString(1, custname);
ResultSet results = pstmt.executeQuery( );
Valide y sanee siempre sus entradas. Dado que algunos caracteres, como "OR 1=1", no van a ser introducidos por un usuario legítimo de tu aplicación, no hay necesidad de permitirlos. Puedes mostrar un mensaje de error al usuario o eliminarlos de tu entrada antes de procesarla.
Al decir esto, no dependas sólo de la validación y la higienización para protegerte. Los humanos inteligentes han encontrado formas de evitarlo. Son buenas estrategias de Defensa en Profundidad (DiD), pero la parametrización es la forma segura de cubrir todas las bases.
Otra buena estrategia de DiD es utilizar el "mínimo privilegio" dentro de la base de datos y la lista blanca de entrada. Aplicar el privilegio mínimo significa que su aplicación no tiene un poder ilimitado dentro de la base de datos. Si un atacante consigue acceder, el daño que puede hacer es limitado.
OWASP tiene una gran hoja de trucos de inyección SQL disponible para mostrar cómo manejar esta vulnerabilidad en varios lenguajes y plataformas... pero si quieres ir más allá, puedes jugar un desafío de inyección SQL en tu lenguaje preferido en nuestra plataforma ahora mismo; aquí hay algunos de los más populares para empezar:
Inyección SQL en Python Django
Comienza el viaje
Has hecho un gran progreso en la comprensión de la inyección SQL, y los pasos necesarios para solucionarlo. ¡Impresionante!
Ya hemos hablado de cómo se produce la inyección SQL; por lo general, un atacante utiliza la entrada para controlar las consultas de su base de datos para sus propios fines nefastos.
También hemos visto los daños causados por la explotación de las vulnerabilidades de inyección SQL: Las cuentas pueden verse comprometidas y se pierden millones de dólares... una pesadilla, y muy cara.
Hemos visto cómo prevenir la inyección SQL:
- Parametrización de las consultas
- Uso de mapeadores relacionales de objetos y procedimientos almacenados
- Validación y lista blanca de entradas de usuarios
Ahora, depende de ti. La práctica es la mejor manera de seguir aprendiendo y dominando el idioma, así que ¿por qué no echas un vistazo a nuestros Recursos de aprendizaje sobre la inyección de SQL, y luego pruebe nuestra demostración gratuita de la plataforma? Estarás en camino de convertirte en un Secure Code Warrior.
En términos sencillos, SQL (o Structured Query Language) es el lenguaje utilizado para comunicarse con las bases de datos relacionales; es el lenguaje de consulta que utilizan los desarrolladores, los administradores de bases de datos y las aplicaciones para gestionar las enormes cantidades de datos que se generan cada día.
Nuestros datos se están convirtiendo rápidamente en una de las mercancías más valiosas del mundo... y cuando algo es valioso, los malos querrán poner sus manos en él para su beneficio.
Los atacantes están utilizando la inyección SQL, una de las vulnerabilidades de datos más antiguas(¡desde 1998!) y más molestas que existen, para robar y cambiar la información sensible disponible en millones de bases de datos de todo el mundo. Es insidiosa, y los desarrolladores deben entender la inyección SQL (así como la forma de defenderse contra ella) si queremos mantener nuestros datos a salvo.
Para ello, discutiremos tres aspectos clave de la inyección SQL:
- Cómo funciona
- Por qué es tan peligroso
- Cómo defenderse
Comprender la Inyección SQL
La inyección SQL se puede entender con una palabra: contexto.
Dentro de una aplicación, existen dos contextos: uno para los datos y otro para el código. El contexto de código indica al ordenador qué debe ejecutar y lo separa de los datos que debe procesar.
La inyección SQL se produce cuando un atacante introduce datos que son tratados erróneamente como código por el intérprete de SQL.
Un ejemplo es un campo de entrada en un sitio web, donde un atacante introduce ''' OR 1=1" y se añade al final de una consulta SQL. Cuando esta consulta se ejecuta, devuelve "true" para cada fila de la base de datos. Esto significa que se devolverán todos los registros de la tabla consultada.
Las implicaciones de la inyección SQL pueden ser catastróficas. Si esto ocurre en una página de inicio de sesión, podría devolver todos los registros de los usuarios, incluyendo posiblemente los nombres de usuario y las contraseñas. Si una simple consulta para sacar datos tiene éxito, las consultas para cambiar los datos también lo harían.
Echemos un vistazo a un código vulnerable para que pueda ver cómo es una vulnerabilidad de inyección SQL en carne y hueso.
Mira este código:
String query = "SELECT account balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
Statement statement = connection.createStatement( ... );
ResultSet results = statement.executeQuery( query );
}
El código aquí simplemente añade la información de los parámetros del cliente al final de la consulta SQL sin ninguna validación. Cuando esto ocurre, un atacante puede introducir código en un campo de entrada o en los parámetros de la URL y se ejecutará.
La clave no es que los atacantes sólo puedan añadir ''' OR 1=1" a cada consulta SELECT, sino que un atacante puede manipular cualquier tipo de consulta SQL (INSERT, UPDATE, DELETE, DROP, etc.) y ampliarla con cualquier cosa que soporte la base de datos. Hay grandes recursos y herramientas disponibles en el dominio público que muestran lo que es posible.
Pronto aprenderemos a corregir este problema. En primer lugar, vamos a entender cuánto daño se puede hacer.
Por qué la inyección SQL es tan peligrosa
Estos son sólo tres ejemplos de infracciones causadas por la inyección SQL:
- El sitio web de la Junta Electoral de Illinois fue violado debido a vulnerabilidades de inyección SQL. Los atacantes robaron los datos personales de 200.000 ciudadanos estadounidenses. Por la naturaleza de la vulnerabilidad encontrada, los atacantes podrían haber modificado también los datos, aunque no lo hicieron.
- Hetzner, una empresa sudafricana de alojamiento de sitios web, sufrió un ataque que afectó a 40.000 registros de clientes. Una vulnerabilidad de inyección SQL condujo al posible robo de todos los registros de clientes de su base de datos.
- Un proveedor de servicios financieros católicos en Minnesota, Estados Unidos, fue vulnerado mediante inyección SQL. Se robaron los datos de las cuentas, incluidos los números de cuenta, de casi 130.000 clientes.
Los datos sensibles pueden utilizarse para hacerse con cuentas, restablecer contraseñas, robar dinero o cometer fraudes.
Incluso la información que no se considera sensible o de identificación personal puede utilizarse para otros ataques. La información de la dirección o los últimos cuatro dígitos de su número de identificación gubernamental pueden ser utilizados para hacerse pasar por usted ante las empresas, o para restablecer su contraseña.
Cuando un ataque tiene éxito, los clientes pueden perder la confianza en la empresa. Recuperarse de los daños en los sistemas o de las multas reglamentarias puede costar millones de dólares.
Pero no tiene por qué acabar así para ti.
Derrotar la inyección SQL
La inyección SQL puede ser derrotada etiquetando claramente las partes de su aplicación, para que el ordenador sepa si una determinada parte son datos o código a ejecutar. Esto puede hacerse utilizando consultas parametrizadas.
Cuando las consultas SQL utilizan parámetros, el intérprete SQL utilizará el parámetro sólo como datos. No lo ejecuta como código.
Por ejemplo, un ataque como ''' OR 1=1" no funcionará. La base de datos buscará la cadena "OR 1=1" y no la encontrará en la base de datos. Simplemente se encogerá de hombros y dirá: "Lo siento, no puedo encontrarlo".
Un ejemplo de consulta parametrizada en Java tiene el siguiente aspecto:
La mayoría de los marcos de desarrollo proporcionan defensas integradas contra la inyección SQL.
Los mapeadores relacionales de objetos (ORM), como Entity Framework en la familia .NET, parametrizan las consultas por defecto. Esto se encargará de la inyección SQL sin ningún esfuerzo por su parte.
Sin embargo, debe saber cómo funciona su ORM específico. Por ejemplo, Hibernate, un ORM muy popular en el mundo de Java, puede ser vulnerable a la inyección SQL si se utiliza de forma incorrecta.
Parametrizar las consultas es la primera y mejor defensa, pero hay otras. Los procedimientos almacenados también admiten parámetros SQL y pueden utilizarse para evitar la inyección SQL. Tenga en cuenta que los procedimientos almacenados también deben ser construidos correctamente para que esto funcione.
// This should REALLY be validated too
String custname = request.getParameter("customerName");
// perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.preparedStatement( query );
pstmt.setString(1, custname);
ResultSet results = pstmt.executeQuery( );
Valide y sanee siempre sus entradas. Dado que algunos caracteres, como "OR 1=1", no van a ser introducidos por un usuario legítimo de tu aplicación, no hay necesidad de permitirlos. Puedes mostrar un mensaje de error al usuario o eliminarlos de tu entrada antes de procesarla.
Al decir esto, no dependas sólo de la validación y la higienización para protegerte. Los humanos inteligentes han encontrado formas de evitarlo. Son buenas estrategias de Defensa en Profundidad (DiD), pero la parametrización es la forma segura de cubrir todas las bases.
Otra buena estrategia de DiD es utilizar el "mínimo privilegio" dentro de la base de datos y la lista blanca de entrada. Aplicar el privilegio mínimo significa que su aplicación no tiene un poder ilimitado dentro de la base de datos. Si un atacante consigue acceder, el daño que puede hacer es limitado.
OWASP tiene una gran hoja de trucos de inyección SQL disponible para mostrar cómo manejar esta vulnerabilidad en varios lenguajes y plataformas... pero si quieres ir más allá, puedes jugar un desafío de inyección SQL en tu lenguaje preferido en nuestra plataforma ahora mismo; aquí hay algunos de los más populares para empezar:
Inyección SQL en Python Django
Comienza el viaje
Has hecho un gran progreso en la comprensión de la inyección SQL, y los pasos necesarios para solucionarlo. ¡Impresionante!
Ya hemos hablado de cómo se produce la inyección SQL; por lo general, un atacante utiliza la entrada para controlar las consultas de su base de datos para sus propios fines nefastos.
También hemos visto los daños causados por la explotación de las vulnerabilidades de inyección SQL: Las cuentas pueden verse comprometidas y se pierden millones de dólares... una pesadilla, y muy cara.
Hemos visto cómo prevenir la inyección SQL:
- Parametrización de las consultas
- Uso de mapeadores relacionales de objetos y procedimientos almacenados
- Validación y lista blanca de entradas de usuarios
Ahora, depende de ti. La práctica es la mejor manera de seguir aprendiendo y dominando el idioma, así que ¿por qué no echas un vistazo a nuestros Recursos de aprendizaje sobre la inyección de SQL, y luego pruebe nuestra demostración gratuita de la plataforma? Estarás en camino de convertirte en un Secure Code Warrior.
Haga clic en el siguiente enlace y descargue el PDF de este recurso.
Secure Code Warrior está a disposición de su organización para ayudarle a proteger el código a lo largo de todo el ciclo de vida de desarrollo de software y crear una cultura en la que la ciberseguridad sea una prioridad. Tanto si es director de AppSec, desarrollador, CISO o cualquier persona implicada en la seguridad, podemos ayudar a su organización a reducir los riesgos asociados a un código inseguro.
Ver el informeReservar una demostraciónJaap Karan Singh es un evangelista de la codificación segura, jefe Singh y cofundador de Secure Code Warrior.
En términos sencillos, SQL (o Structured Query Language) es el lenguaje utilizado para comunicarse con las bases de datos relacionales; es el lenguaje de consulta que utilizan los desarrolladores, los administradores de bases de datos y las aplicaciones para gestionar las enormes cantidades de datos que se generan cada día.
Nuestros datos se están convirtiendo rápidamente en una de las mercancías más valiosas del mundo... y cuando algo es valioso, los malos querrán poner sus manos en él para su beneficio.
Los atacantes están utilizando la inyección SQL, una de las vulnerabilidades de datos más antiguas(¡desde 1998!) y más molestas que existen, para robar y cambiar la información sensible disponible en millones de bases de datos de todo el mundo. Es insidiosa, y los desarrolladores deben entender la inyección SQL (así como la forma de defenderse contra ella) si queremos mantener nuestros datos a salvo.
Para ello, discutiremos tres aspectos clave de la inyección SQL:
- Cómo funciona
- Por qué es tan peligroso
- Cómo defenderse
Comprender la Inyección SQL
La inyección SQL se puede entender con una palabra: contexto.
Dentro de una aplicación, existen dos contextos: uno para los datos y otro para el código. El contexto de código indica al ordenador qué debe ejecutar y lo separa de los datos que debe procesar.
La inyección SQL se produce cuando un atacante introduce datos que son tratados erróneamente como código por el intérprete de SQL.
Un ejemplo es un campo de entrada en un sitio web, donde un atacante introduce ''' OR 1=1" y se añade al final de una consulta SQL. Cuando esta consulta se ejecuta, devuelve "true" para cada fila de la base de datos. Esto significa que se devolverán todos los registros de la tabla consultada.
Las implicaciones de la inyección SQL pueden ser catastróficas. Si esto ocurre en una página de inicio de sesión, podría devolver todos los registros de los usuarios, incluyendo posiblemente los nombres de usuario y las contraseñas. Si una simple consulta para sacar datos tiene éxito, las consultas para cambiar los datos también lo harían.
Echemos un vistazo a un código vulnerable para que pueda ver cómo es una vulnerabilidad de inyección SQL en carne y hueso.
Mira este código:
String query = "SELECT account balance FROM user_data WHERE user_name = "
+ request.getParameter("customerName");
try {
Statement statement = connection.createStatement( ... );
ResultSet results = statement.executeQuery( query );
}
El código aquí simplemente añade la información de los parámetros del cliente al final de la consulta SQL sin ninguna validación. Cuando esto ocurre, un atacante puede introducir código en un campo de entrada o en los parámetros de la URL y se ejecutará.
La clave no es que los atacantes sólo puedan añadir ''' OR 1=1" a cada consulta SELECT, sino que un atacante puede manipular cualquier tipo de consulta SQL (INSERT, UPDATE, DELETE, DROP, etc.) y ampliarla con cualquier cosa que soporte la base de datos. Hay grandes recursos y herramientas disponibles en el dominio público que muestran lo que es posible.
Pronto aprenderemos a corregir este problema. En primer lugar, vamos a entender cuánto daño se puede hacer.
Por qué la inyección SQL es tan peligrosa
Estos son sólo tres ejemplos de infracciones causadas por la inyección SQL:
- El sitio web de la Junta Electoral de Illinois fue violado debido a vulnerabilidades de inyección SQL. Los atacantes robaron los datos personales de 200.000 ciudadanos estadounidenses. Por la naturaleza de la vulnerabilidad encontrada, los atacantes podrían haber modificado también los datos, aunque no lo hicieron.
- Hetzner, una empresa sudafricana de alojamiento de sitios web, sufrió un ataque que afectó a 40.000 registros de clientes. Una vulnerabilidad de inyección SQL condujo al posible robo de todos los registros de clientes de su base de datos.
- Un proveedor de servicios financieros católicos en Minnesota, Estados Unidos, fue vulnerado mediante inyección SQL. Se robaron los datos de las cuentas, incluidos los números de cuenta, de casi 130.000 clientes.
Los datos sensibles pueden utilizarse para hacerse con cuentas, restablecer contraseñas, robar dinero o cometer fraudes.
Incluso la información que no se considera sensible o de identificación personal puede utilizarse para otros ataques. La información de la dirección o los últimos cuatro dígitos de su número de identificación gubernamental pueden ser utilizados para hacerse pasar por usted ante las empresas, o para restablecer su contraseña.
Cuando un ataque tiene éxito, los clientes pueden perder la confianza en la empresa. Recuperarse de los daños en los sistemas o de las multas reglamentarias puede costar millones de dólares.
Pero no tiene por qué acabar así para ti.
Derrotar la inyección SQL
La inyección SQL puede ser derrotada etiquetando claramente las partes de su aplicación, para que el ordenador sepa si una determinada parte son datos o código a ejecutar. Esto puede hacerse utilizando consultas parametrizadas.
Cuando las consultas SQL utilizan parámetros, el intérprete SQL utilizará el parámetro sólo como datos. No lo ejecuta como código.
Por ejemplo, un ataque como ''' OR 1=1" no funcionará. La base de datos buscará la cadena "OR 1=1" y no la encontrará en la base de datos. Simplemente se encogerá de hombros y dirá: "Lo siento, no puedo encontrarlo".
Un ejemplo de consulta parametrizada en Java tiene el siguiente aspecto:
La mayoría de los marcos de desarrollo proporcionan defensas integradas contra la inyección SQL.
Los mapeadores relacionales de objetos (ORM), como Entity Framework en la familia .NET, parametrizan las consultas por defecto. Esto se encargará de la inyección SQL sin ningún esfuerzo por su parte.
Sin embargo, debe saber cómo funciona su ORM específico. Por ejemplo, Hibernate, un ORM muy popular en el mundo de Java, puede ser vulnerable a la inyección SQL si se utiliza de forma incorrecta.
Parametrizar las consultas es la primera y mejor defensa, pero hay otras. Los procedimientos almacenados también admiten parámetros SQL y pueden utilizarse para evitar la inyección SQL. Tenga en cuenta que los procedimientos almacenados también deben ser construidos correctamente para que esto funcione.
// This should REALLY be validated too
String custname = request.getParameter("customerName");
// perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.preparedStatement( query );
pstmt.setString(1, custname);
ResultSet results = pstmt.executeQuery( );
Valide y sanee siempre sus entradas. Dado que algunos caracteres, como "OR 1=1", no van a ser introducidos por un usuario legítimo de tu aplicación, no hay necesidad de permitirlos. Puedes mostrar un mensaje de error al usuario o eliminarlos de tu entrada antes de procesarla.
Al decir esto, no dependas sólo de la validación y la higienización para protegerte. Los humanos inteligentes han encontrado formas de evitarlo. Son buenas estrategias de Defensa en Profundidad (DiD), pero la parametrización es la forma segura de cubrir todas las bases.
Otra buena estrategia de DiD es utilizar el "mínimo privilegio" dentro de la base de datos y la lista blanca de entrada. Aplicar el privilegio mínimo significa que su aplicación no tiene un poder ilimitado dentro de la base de datos. Si un atacante consigue acceder, el daño que puede hacer es limitado.
OWASP tiene una gran hoja de trucos de inyección SQL disponible para mostrar cómo manejar esta vulnerabilidad en varios lenguajes y plataformas... pero si quieres ir más allá, puedes jugar un desafío de inyección SQL en tu lenguaje preferido en nuestra plataforma ahora mismo; aquí hay algunos de los más populares para empezar:
Inyección SQL en Python Django
Comienza el viaje
Has hecho un gran progreso en la comprensión de la inyección SQL, y los pasos necesarios para solucionarlo. ¡Impresionante!
Ya hemos hablado de cómo se produce la inyección SQL; por lo general, un atacante utiliza la entrada para controlar las consultas de su base de datos para sus propios fines nefastos.
También hemos visto los daños causados por la explotación de las vulnerabilidades de inyección SQL: Las cuentas pueden verse comprometidas y se pierden millones de dólares... una pesadilla, y muy cara.
Hemos visto cómo prevenir la inyección SQL:
- Parametrización de las consultas
- Uso de mapeadores relacionales de objetos y procedimientos almacenados
- Validación y lista blanca de entradas de usuarios
Ahora, depende de ti. La práctica es la mejor manera de seguir aprendiendo y dominando el idioma, así que ¿por qué no echas un vistazo a nuestros Recursos de aprendizaje sobre la inyección de SQL, y luego pruebe nuestra demostración gratuita de la plataforma? Estarás en camino de convertirte en un Secure Code Warrior.
Índice
Jaap Karan Singh es un evangelista de la codificación segura, jefe Singh y cofundador de Secure Code Warrior.
Secure Code Warrior está a disposición de su organización para ayudarle a proteger el código a lo largo de todo el ciclo de vida de desarrollo de software y crear una cultura en la que la ciberseguridad sea una prioridad. Tanto si es director de AppSec, desarrollador, CISO o cualquier persona implicada en la seguridad, podemos ayudar a su organización a reducir los riesgos asociados a un código inseguro.
Reservar una demostraciónDescargarRecursos para empezar
Evaluación comparativa de las competencias en materia de seguridad: optimización del diseño seguro en la empresa
El movimiento Secure-by-Design es el futuro del desarrollo de software seguro. Conozca los elementos clave que las empresas deben tener en cuenta cuando piensan en una iniciativa Secure-by-Design.
DigitalOcean reduce su deuda de seguridad con Secure Code Warrior
El uso por parte de DigitalOcean de la formación Secure Code Warrior ha reducido significativamente la deuda de seguridad, permitiendo a los equipos centrarse más en la innovación y la productividad. La mejora de la seguridad ha reforzado la calidad de sus productos y su ventaja competitiva. De cara al futuro, SCW Trust Score les ayudará a seguir mejorando las prácticas de seguridad y a continuar impulsando la innovación.
Recursos para empezar
La puntuación de confianza revela el valor de las iniciativas de mejora de la seguridad mediante el diseño
Nuestra investigación ha demostrado que la formación en código seguro funciona. Trust Score, que utiliza un algoritmo basado en más de 20 millones de puntos de datos de aprendizaje procedentes del trabajo de más de 250 000 alumnos en más de 600 organizaciones, revela su eficacia a la hora de reducir las vulnerabilidades y cómo hacer que la iniciativa sea aún más eficaz.
Seguridad reactiva frente a seguridad preventiva: Prevenir es mejor que curar
La idea de introducir la seguridad preventiva en el código y los sistemas heredados al mismo tiempo que en las aplicaciones más recientes puede parecer desalentadora, pero un planteamiento basado en el diseño seguro, aplicado mediante la mejora de las competencias de los desarrolladores, puede aplicar las mejores prácticas de seguridad a esos sistemas. Es la mejor oportunidad que tienen muchas organizaciones de mejorar su seguridad.
Ventajas de la evaluación comparativa de las competencias de seguridad de los desarrolladores
La creciente atención que se presta al código seguro y a los principios del diseño seguro exige que los desarrolladores reciban formación en ciberseguridad desde el principio del proceso de desarrollo de software, con herramientas como Secure Code Warrior's Trust Score, que ayudan a medir y mejorar sus progresos.
Impulsando iniciativas de seguridad por diseño para empresas con éxito significativo
Nuestro último documento de investigación, Benchmarking Security Skills: Streamlining Secure-by-Design in the Enterprise, es el resultado de un análisis profundo de iniciativas reales de Secure-by-Design a nivel empresarial y de la derivación de enfoques de mejores prácticas basados en hallazgos basados en datos.