Mes: junio 2009

Entendiendo los ataques CSRF

Acabo de leer un interesante artículo  en Linux Magazine en el que se explica cómo funcinan los ataques tipo CSRF (cross-site  request forgery o también cross-site reference forgery que vendría a ser algo así como falsificación de petición/referencia cruzada a un sitio). Voy a intentar explicarla brevemente.

Actualmente la mayoría de los navegadores nos permiten tener varias ventanas y/o pestañas abiertas que comparten cierta información. Por ejemplo, si tenemos abierta una sesión de gmail y en otra pestaña abrimos nuestro adsense automáticamente nos autentificará con la cuenta de gmail de la sesión activa. Si a esto le añadimos que cada vez existen más aplicaciones web que tenemos constantemente abiertas tenemos un problema.

Imaginemos que mantenemos nuestra cuenta de correo web abierta y en otra pestaña abrimos nuestra sesión en una red social, en ese momento nos encontamos a un contacto que conoce nuestra dirección de correo-e y al que no se le ocurre otra cosa que montarnos una trampa en forma de javascript o url montada aproposito escondida en una imagen o cualquier otro elemento para que lo visitemos en su perfil de la red social. Con esto esa persona podría conseguir que cargaramos por ejemplo una url con esta forma.

http://dominio-mi-correo-web.com/contrasenya?nombre=midireccion@correo.com&contrasenya=nuevacontraseña

A tenor de lo explicado anteriormente nuestro navegador ejecutaría dicho código al tener la sesión de nuestro correo-e abierta y con ello esa tercera persona ha conseguido usurparnos nuestra cuenta de correo-e de la forma más absurda.

Os preguntaréis como nos va a meter esa url sin que nos demos cuenta. Pues es muy fácil, que se ejecute un javascript o que lance una url mediante un enlace incrustado en un texto es de lo más sencillo. También tenemos cosas ligeramente más sofisticadas como las citadas en el artículo que consisten en poner la url en el src de una imagen.

Ahora que sabemos como funciona tenemos que pensar en cómo evitarlo. La propuesta del artículo consiste en crear una señal en el servidor que generaremos de forma aleatoria antes de enviar una página de solicitud de información como puede ser un formulario. Posteriormente ya sea mediante un campo oculto de formulario, una cookie o una url deberemos recibir de nuevo esa señal para cotejarla con la original y así asegurar que no es una inyección mediane el truco anteriormente descrito sinó que es consecuencia de la ejecución de una página generada por nosotros. En el escenario anterior la url que montaba la tercera parte no funcionaría ya que le faltaría un tercer parámetro que sería la señal que habíamos generado aleatoriamente.

Otras sugerencias son:

  1. Utilizar un navegador en exclusiva para este tipo de aplicaciones.
  2. Utilizar un navegador que aisle cada pestaña como puede ser el nuevo chrome de google.

Por lo que se comenta en el artículo pocas páginas están diseñadas para evitar ataques XSS y particularmente del tipo CSRF. Tendremos que ponernos las pilas.

Cheli

El sistema electoral se ha quedado obsoleto

Soy de la opinión que ya que nos dan la oportunidad de decidir quienes van a ser nuestros representantes, y a pesar que la política cada día me aburre más (para ver a histéricos/cas tirándose de los pelos casi que prefiero gran hermano), hay que aprovecharla. Por consiguiente estaba decidido a ir a votar este domingo pero no me va a ser posible.

El problema es que no soy adivino y hasta hace dos días no sabía que me iba a resultar imposible presentarme a la mesa electoral que me corresponde para ejercer mi derecho al voto. La cuestión es que tal y como está montado ahora el tinglado o bien votas por correo con unas semanas de anticipación o bien votas el día que toca presentandote a la mesa electoral del pueblo/ciudad donde estás empadronado, no hay más.

Lo increible es que en un mundo globalizado y con el nivel de vida y descentralización que hay no pueda ejercer el derecho al voto porque justamente este domingo no voy a estar en mi pueblo y en el momento que supe que no podía asistir ya no se podía votar por correo. Tampoco es que me vaya a marte, me voy a una ciudad española pero mira tú por dónde que presentando tu DNI puedes hacer casi cualquier cosa estés donde estés pero votar no puedes.

Me tiene un tanto indignado pero habrá que aguantarse. A ver si los políticos se modernizan un poco y cambian estas limitaciones absurdas.

Cheli

¿Por qué el sistema de módulos y plantillas no aporta ventajas al desarrollo de Openbravo ERP?

Para poder entender que ha cambiado o mejor dicho, que no ha cambiado al desarrollar sobre Openbravo ERP después de la introducción del sistema de módulos y plantillas en la versión 2.50 tendremos que hacer un poco de historia de lo que teníamos antes.

En versiones anteriores a la 2.50 la recomendación de openbravo a la hora de introducir un desarrollo propio era meterlo en un directorio que existía por defecto en el árbol de código llamado srcClient. ¿En qué consistía esta metodología? es muy fácil de explicar, si querías introducir un nuevo archivo de código lo que debías de hacer era replicar el árbol de directorios donde se iba a ubicar dicho archivo en src/ pero sobre srcClient, pongamos un ejemplo.

Si yo necesitaba como desarrollador añadir un nuevo informe (un archivo jrxml de jasper) que iba a estar ubicado en src/org/openbravo/erpReports lo que tenía que hacer es lo siguiente:

  1. Replicar el árbol de directorios donde va a quedar ubicado el archivo pero en srcClient.
    mkdir srcClient/org
    mkdir srcClient/org/openbravo
    mkdir srcClient/org/openbravo/erpReports
  2. Copiar el archivo a esa ubicación
    mv archivo.jrxml srcClient/org/openbravo/erpReports

Ahora al compilar el codigo lo que hacía la tarea ant correspondiente era copiar todo lo que encontraba en srcClient y lo volcaba en src sobreescribiendo los archivos originales si se diera el caso para posteriormente empezar la compilación. Con esto lo que conseguíamos es tener nuestros desarrollos separados del resto de código, única y exclusivamente, pero no nos servía para nada más. Yo como siempre utilizo un sistema de control de versiones no le veía ninguna ventaja a este método ya que en el histórico de mi scv tenía qué archivos había tocado y qué había hecho con ellos por lo que los cambios siempre se hacen directamente en la rama src. Mi opinión es que si utilizas un scv el método de srcClient es completamente inútil.

A este método hay que sumarle una serie de inconvenientes adicionales. Por ejemplo, si queríamos modificar un archivo ya existente en openbravo (core) tenías que hacer una copia sobre srcClient y modificarlo ahí. Si ahora en algún momento se aplicaba un cambio al core que involucrara a ese archivo el primer problema es que el archivo que encontraba el actualizador era una copia del tuyo (srcClient) pero en src (recordemos que al compilar se machaca la versión src con la de srcClient) con lo que ya teníamos los primeros problemas de conflicto de código. Lo que te tocababa hacer si utilizabas srcClient es:

  1. recuperar la version original del archivo sin tus cambios y colocarla en su lugar en src.
  2. Aplicar la actualización de openbravo para ese archivo con lo que no se produciría ningún conflicto.
  3. Y por último integrar (hacer merge) de los cambios de ese archivo en tu versión en srcClient para que funcionara.

La otra opción sería la misma que si no utilizaras srcClient, o lo que es lo mismo la que he estado utilizando yo que consiste en:

  1. Aplicar la actualización de openbravo para ese archivo con lo que si ese archivo es consecuencia de un archivo en srcClient (insito en que machaca sobre src) o de una modificación directa en src, cabe la posibilidad de que exista un conflicto.
  2. Resolver el conflicto.
  3. En caso de que ese archivo fuera consecuencia de uno en srcClient tendríamos que actualizarlo en este árbol (srcClient).

¿Cómo funciona el sistema de módulos?, en esencia es muy parecido a srcClient. Cuando vas a crear un módulo debes crear un directorio al estilo srcClient para recrear los archivos, sean del core o no, y su posición en el árbol de código en el directorio de soporte para el módulo (llamémoslo moduleClient, esto es una convención que me acabo de inventar por si alguien no se había dado cuenta). Lo que sucede ahora es que cuando se actualiza el core lo que hace openbravo es desacoplar todos los módulos (limpiar todo el código moduleClient de todos los módulos), dejándo el código original de la versión de core instalada y sobre esa aplicar la actualización al siguiente (hacen merge) así se aseguran que el actualizador de OB ahora ya no va a tener virtualmente coflicto alguno. Pero el problema lo volvemos a tener en el momento de volver a acoplar los módulos (volver a meter el código moduleClient) igual que lo teníamos con srcClient de ahí que diga que virtualmente no hay conflictos ya que realmente hay exactamente los mismos conflictos que en cualquier otra versión anterior.

Como dije en un comentario a Pepe, ahora OB puede afirmar con rigor frases propagandísticas del tipo “Hemos solventado los problemas de actualizaciones, ahora ya no vamos a tener ningún conflicto y actualizar el core es tan sencillo como dar un click”. Pero si uno tiene dos dedos de frente y sabe como funciona openbravo sabría que la magia no existe y pensaría lo que suelo pensar yo en estos casos ¡estos se piensan que soy imbécil!.

Aquí no se queda la historia, ni siquiera los que toman las decisiones de diseño en OB saben como van a mantener la compatibilidad de módulos en versiones posteriores. Cuando le vieron las orejas al lobo pensaron, bueno vamos a intentar mantener lo más estable posible las partes del core que son subsceptibles de desarrollo por parte de terceros y a esto lo vamos a llamar API, que en cierta manera lo es, pero hacer eso como toda compatibilidad hacia atrás y sobretodo con un desarrollo tan poco estable como el que lleva OB es imposible.

Al final pasan cosas como por ejemplo si mi código moduleClient contiene una modificación en el core y por alguna razón como puede ser corregir un bug en el core OB necesita cambiar algo de esa supuesta API (crear o eliminar campos, modificar la interfaz de un método de una clase, etc) que pueda afectar a los desarrollos de terceros lo que hacen es publicarlo en una página de wiki para que lo tengas en cuenta. En menos de dos meses ya llevan 19 cambios en esa API.

Hablando incluso con algunos desarrolladores proponen alguna solución de compromiso pero que no dejan de ser chapucillas poco elegantes, a mi a veces me ha tocado hacer alguna de estas. Sigamos con los ejemplos, imaginemos que en mi código moduleClient tengo un archivo del core y en la siguiente versión del core se modifica, pues una de las propuestas es que dejes tu antiguo archivo del core que tienes en tu moduleClient sin las nuevas modificaciones. Esto tiene un peligro que es que si el desarrollo que provocó el cambio en ese archivo también afecta a otros archivos y tu mantienes la versión anterior puede que no compile o que funcionalmente casque. No te queda más remedio que o bien integrar el cambio en tu archivo del core que tienes en tu moduleClient o revisar si realmente se va a romper la aplicación.

Otro ejemplo que me llegó hace poco en una propuesta de un desarrollador de OB era, -bueno cuando tengas que hacer una modificación en una ventana del core duplícala de forma que las mejoras que se apliquen a esa ventana se harán sin conflictos en la ventana origina que dejarás oculta y tu seguirás con tu versión de ventana sin aplicar ningún cambio ni mejora-. Esta en cierta manera me alarmó ya que si se pretende vender el soporte de actualizaciones automáticas y de forma transparente en network pero para evitar problemas lo que haces es rodear el sistema para que no se apliquen en la versión del cliente pues no sirve de nada.

Por último comentar que respecto a una consideración que me hacía Pepe en la que indicaba que el sistema de módulos permite organizar mejor los desarrollos vuelvo a no coincidir. Los desarrolladores para este fin lo que hacen es utilizar un sistema de control de versiones que aporta muchísimas más ventajas en organización y reutilización de código que el hecho de poder paquetizarlo.

Un ejemplo sería que podemos ir al detalle que queramos en las modificaciones. Si queremos aplicar una modificación que hemos desarrollado para un cliente pero para ello hay que aplicar un módulo entero a lo mejor puede implicar que al margen de esa modificación se vayan a aplicar otras que no deseamos, o alrevés, requerir de varios módulos para una única modificación. Para esto tenemos el sistema de control de versiones, sus ramas, etiquetas y demás mecanismos.

El hecho de generar un diff y aplicar con patch es inmediato en el momento que has superado la curva de aprendizaje de este tipo de herramientas. Y ahora con los sistemas descentralizados tienes aún más ventajas como poder hacer push contra la rama local de los desarrolladores que te interesen, etc etc.

Espero haber sido claro y haber podido explicar porque considero que los módulos y plantillas no aportan nada o muy poco al desarrollo en Openbravo ERP pero por otra parte si aportan mucho a la hora de generar entregables.

Un saludo.