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
La potencia de OpenText Fortify + Secure Code Warrior
OpenText Fortify y Secure Code Warrior unen sus fuerzas para ayudar a las empresas a reducir riesgos, transformar a los desarrolladores en campeones de la seguridad y fomentar la confianza de los clientes. Más información aquí.
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.
Recursos para empezar
10 predicciones clave: Secure Code Warrior sobre la influencia de la IA y el diseño seguro en 2025
Las organizaciones se enfrentan a decisiones difíciles sobre el uso de la IA para apoyar la productividad a largo plazo, la sostenibilidad y el retorno de la inversión en seguridad. En los últimos años nos ha quedado claro que la IA nunca sustituirá por completo el papel del desarrollador. Desde las asociaciones entre IA y desarrolladores hasta las crecientes presiones (y confusión) en torno a las expectativas de seguridad por diseño, echemos un vistazo más de cerca a lo que podemos esperar durante el próximo año.
OWASP Top 10 para aplicaciones LLM: Novedades, cambios y cómo mantenerse seguro
Manténgase a la vanguardia de la seguridad de las aplicaciones LLM con las últimas actualizaciones del Top 10 de OWASP. Descubra qué hay de nuevo, qué ha cambiado y cómo Secure Code Warrior le equipa con recursos de aprendizaje actualizados para mitigar los riesgos en la IA Generativa.
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.