Nota: este artículo ha sido escrito por Brant Burnett de Software CenterEdge, una empresa que desarrolla software de TPV y especializado para las industrias de parques de atracciones, ocio y entretenimiento.

Visión general

N1QL es una nueva herramienta increíblemente potente que ayudará a acercar las bases de datos NoSQL a un mayor número de desarrolladores con una curva de aprendizaje mucho menor. Esto ayudará a los desarrolladores a crear aplicaciones avanzadas, eficaces y robustas de forma más rápida y sencilla que nunca. Pero con cualquier nueva tecnología, la superficie de ataque de los piratas informáticos aumenta de forma inherente.

La inyección SQL es un conocido fallo de seguridad que se encuentra habitualmente en aplicaciones basadas en SQL, y que ha sido muy bien documentado a lo largo de los años. Entonces, ¿cómo se compara N1QL con SQL en términos de seguridad? ¿Es N1QL también vulnerable a los ataques de inyección? En caso afirmativo, ¿cómo pueden los desarrolladores evitar estas trampas?

Revisión de la inyección SQL

La inyección SQL es una forma de inyección de código en la que el usuario final puede añadir código malicioso a las consultas SQL que ejecuta su aplicación. Un ejemplo sencillo es esta consulta:

Si el desarrollador no toma medidas para proteger su aplicación, el usuario puede incluir texto malicioso en el campo userName. Por ejemplo:

Esta consulta es el resultado de que el usuario introduzca "' OR '1'='1". Ahora la consulta devolverá todos los usuarios del sistema al usuario malicioso.

Para permitir alteraciones más potentes de la consulta, el usuario malicioso también podría utilizar comentarios para excluir parte de la consulta del desarrollador. Ampliando el ejemplo anterior:

Podría inyectarse:

Como SQL ignorará todo el texto después de "-", la restricción de que el grupo debe ser 5 se elimina ahora de la consulta. Una vez más, todos los usuarios del sistema se devuelven al usuario malicioso.

El usuario también podría combinar los comentarios con comandos por lotes para alterar los datos de su base de datos:

¿Cómo afecta esto a N1QL?

Después de algunos experimentos, N1QL es en realidad más resistente a los ataques de inyección que el SQL tradicional. Por ejemplo, N1QL no soporta actualmente el procesamiento por lotes de múltiples comandos. Por lo tanto, no hay equivalente a los ataques por lotes que permiten modificaciones maliciosas de datos en SQL. Por ejemplo, este ataque de inyección, que podría funcionar en SQL, se rechaza como sintaxis no válida:

Sin embargo, todavía hay opciones para que un usuario malintencionado realice un ataque. Sin protección, estos ataques podrían permitir el acceso a datos protegidos, o la denegación de servicio porque las consultas alteradas utilizan demasiada potencia de procesamiento en el clúster de Couchbase.

Adicionalmente, algunas características como el batching podrían ciertamente ser añadidas en una futura versión de N1QL. Por lo tanto, si los desarrolladores no protegen las entradas de los usuarios en sus consultas, la modificación de los datos podría convertirse en un problema en el futuro.

Modificaciones de la cláusula de destino

Al igual que la inyección SQL, la inyección N1QL permite alterar la cláusula WHERE. Por ejemplo:

Puede llegar a ser:

Debido a las reglas de precedencia de los operadores AND y OR, este ataque puede funcionar incluso si hay cláusulas adicionales:

Todavía devuelve todos los usuarios cuando se convierte en:

N1QL Comentarios

El sistema de comentarios de N1QL usa bloques de comentarios estilo C (/* comment */) en lugar de usar "-" para comentar el resto de la línea. Esto protege a N1QL de algunos de los ataques de inyección más avanzados. Dado que N1QL requiere un comentario de cierre */, los atacantes no pueden comentar partes de su consulta sin causar un error de sintaxis.

Tenga en cuenta, sin embargo, que esto depende de que el desarrollador no deje comentarios en su consulta. Si hay un comentario en el texto de la consulta, el usuario dispone ahora de un bloque de comentarios de cierre que puede utilizar en su beneficio:

Puede inyectarse con "OR 1=1 /*":

Como en el ejemplo SQL, la restricción de grupo se elimina ahora de la consulta.

Inyección de identificadores N1QL

El modelo de documento sin esquema de Couchbase crea una nueva e interesante área de ataque. Cuando se trabaja con SQL, es muy raro incluir la entrada del usuario en cualquier lugar excepto en la cláusula WHERE u ORDER BY de tu consulta. Esto se debe a que los nombres de las tablas y columnas son bien conocidos y no cambian.

La falta de un esquema para los documentos de Couchbase, sin embargo, significa que los desarrolladores podrían verse tentados a permitir que el usuario controle qué campos están seleccionando del documento.

Después de la inyección se convierte:

Ahora el atacante tiene acceso a datos de un documento de contraseña relacionado que no estaba en el documento de usuario que el desarrollador especificó.

Cómo proteger su aplicación

Afortunadamente, es tan fácil proteger tu aplicación de ataques de inyección N1QL como de ataques de inyección SQL. Aquí tienes algunas pautas que facilitan la seguridad. Los ejemplos son en C#, pero los conceptos se aplican igual de bien a cualquier otro lenguaje.

  1. Buenas prácticas: En lugar de insertar la entrada del usuario directamente en su consulta, utilice parámetros con nombre o posicionales como protección. De esta forma, la entrada del usuario nunca se añade directamente a su consulta, proporcionando una protección 100% contra todos los ataques de inyección.

    Debería serlo:
  2. Buena práctica #2: Utilizar una construcción de lenguaje fuertemente tipado, como POCOs de .Net o POJOs de Java, que generen el texto de la consulta. Por ejemplo, la biblioteca Linq2Couchbase (https://github.com/couchbaselabs/Linq2Couchbase) gestiona el escape adecuado al generar N1QL a partir de consultas LINQ.
  3. Si insertas cadenas de texto en la consulta, escapa siempre de las comillas. Sustituye las comillas simples (') por dos comillas simples (").

    Debería serlo:
  4. Al insertar identificadores de entrada de usuario en su consulta, escape siempre el identificador con tildes (). A continuación, sustituya cualquier instancia de una garrapata en la entrada por dos garrapatas (`). Tenga en cuenta que no existe un parámetro con nombre equivalente para los identificadores, por lo que escapar es el identificador es la mejor solución.

    Debería serlo:
  5. Si implementas las otras reglas, también estarás protegido contra ataques basados en comentarios. Sin embargo, una política secundaria contra comentarios en consultas que contengan entradas del usuario puede proporcionar protección adicional en caso de que un desarrollador olvide las otras reglas. En su lugar, basta con poner los comentarios en el código de la aplicación en lugar de en la propia consulta.

    Debería serlo:

Para ver ejemplos de estos ataques y sus métodos de protección en C#, consulte este repositorio de GitHub: https://github.com/brantburnett/N1QlInjection. Tenga en cuenta que necesitará Couchbase instalado localmente y con beer-sample instalado para ejecutar las pruebas.

Conclusión

Aunque N1QL es vulnerable a ataques de inyección, esta vulnerabilidad no es peor que vulnerabilidades bien conocidas en SQL. Además, es muy fácil para los desarrolladores protegerse contra ataques de inyección. Por lo tanto, N1QL proporciona una excelente plataforma para desarrollar aplicaciones seguras utilizando bases de datos Couchbase NoSQL.

Autor

Publicado por Jeff Morris, Ingeniero Superior de Software, Couchbase

Jeff Morris es Ingeniero de Software Senior en Couchbase. Antes de unirse a Couchbase, Jeff pasó seis años en Source Interlink como Arquitecto Web Empresarial. Jeff es responsable del desarrollo de los SDK de Couchbase y de cómo integrarse con N1QL (lenguaje de consulta).

Dejar una respuesta