Ética para desarrolladores: ¿tu aplicación intenta manipular al usuario?

Desgraciadamente, hoy en día existe una gran diversidad de software con propósitos malintencionados: el ransomware que quiere cifrar todo tu disco duro para pedirte un rescate, el keylogger que quiere interceptar las pulsaciones de tu teclado para robarte las contraseñas, la barra de herramientas que registra todo tu historial de visitas y añade anuncios a las páginas web, el troyano que quiere grabarte usando tu webcam, … Pero sin necesidad de irse al mundo del malware, la industria del software es muy competitiva y algunas empresas a pierden las buenas maneras a la hora de diseñar sus aplicaciones o servicios. El objetivo: maximizar sus beneficios sin tener en cuenta las consecuencias. Como reza el dicho, “más vale pedir perdón que pedir permiso” y cada vez más aplicaciones actúan según esta premisa. Pongamos un ejemplo muy habitual: opt-in vs opt-out. Cuando se ofrece un servicio adicional a un usuario, hay dos formas de proponerlo. El primero es el modelo opt-in: si el usuario desea el servicio, debe hacer alguna acción para solicitarlo (apretar el botón “Aceptar”, hacer click en un enlace, marcar un checkbox, …). El segundo es el modelo opt-out: si el usuario no lo desea, debe realizar acciones para cancelarlo (el botón “Unsubscribe” de una newsletter, desmarcar un checkbox marcado por defecto, …). Últimamente, muchas aplicaciones y servicios optan por el modelo opt-out, con el agravante de ser poco transparentes a la hora de ofrecer el nuevo servicio: Informar sobre el nuevo servicio de forma poco llamativa. Ocultar la descripción del nuevo servicio en un gran volumen de información. Presentar el nuevo servicio como una actualización del actual o la solución a un error o problema de seguridad en el equipo. Es por esto que...

Ofuscación de código: te reto a que entiendas este programa

Uno de los aspectos más valorados en el código fuente de un proyecto software es su facilidad de comprensión. Si es factible entender cómo funciona el código, entonces es más sencillo corregir errores y añadir nuevas funcionalidades. Además, es más fácil que otras personas más allá del autor puedan participar y contribuir al proyecto. Todos estos son, precisamente, aspectos clave en el desarrollo de proyectos de código abierto. Sin embargo, existen algunas situaciones en los que la facilidad de comprensión no es un valor añadido sino todo lo contrario. Es decir, ¿qué pasa si no queremos que se sepa cómo funciona un programa? Si el lenguaje de programación es compilado, aquí ya hay una primera barrera: el binario no es tan sencillo de entender como el código fuente, aunque no es una barrera insalvable. Pero si es un lenguaje interpretado, el código fuente está a nuestra disposición. Entonces, ¿cómo lo hacemos para ocultar el comportamiento de nuestro código? Aquí es donde entran en acción las herramientas de ofuscación de código. Según el Diccionario de la Real Academia, ofuscar significa “oscurecer y hacer sombra” o “trastornar, conturbar o confundir las ideas, alucinar”. Precisamente, la ofuscación de código es el proceso que intenta modificar un programa para hacer más compleja su comprensión. La ofuscación perfecta es imposible, porque tarde o temprano hay que decirle al ordenador lo que tiene que hacer, pero pueden darse suficientes “rodeos” para confundir a quién esté analizando nuestro programa (ya sea un humano o una herramienta automática). Las técnicas que pueden usarse para ofuscar un programa son muy variadas: Eliminar comentarios, espacios en blanco y saltos de línea (o a la inversa, introducirlos aleatoriamente para dificultar la lectura). Modificar los...

eSports: atletas frente a la pantalla

No hay discusión alguna en el auge en la popularidad de los videojuegos en la cultura popular. Quizás sea por la mejora de la tecnología, por el auge de los juegos casual para dispositivos móviles, porque la primera generación de jugadores de videojuegos se ha hecho mayor (y sigue jugando)… o una combinación de los anteriores. Pero ya hay quién compara los videojuegos con el cine o la literatura por su potencial narrativo prácticamente ilimitado. Algunos géneros del videojuego se apartan de este aspecto de story-telling para apostar por la interacción entre los jugadores. Por ejemplo, la mayoría de MMORPG (massively multiplayer online role playing games) tienen como reclamo la posibilidad de vivir aventuras con tus amig@s. Y cuando decimos interacción… no podemos dejar de lado la competición. Algunos géneros tienen una venerable tradición desde los tiempos de las máquinas recreativas, como los juegos de lucha (Street Fighter, etc). Internet ha permitido ampliar el círculo de los rivales a todo el mundo, hecho que ha dado alas a diversos géneros cuyo principal atractivo es el modo player vs player. Entre ellos, los tres reyes indiscutibles son tres acrónimos: MOBA (multiplayer online battle arena como DotA 2, League of Legends o Heroes of the Storm), FPS (first-person shooter como Call of Duty) y RTS (real-time strategy como  Starcraft). En este mundillo hay auténticos virtuosos, capaces de auténticas maravillas con un teclado/ratón o el mando de una consola. Y como pasa en el mundo del deporte, hay gente dispuesta a pagar por verles en acción. Tanta atención atrae a patrocinadores y anunciantes, que permiten organizar campeonatos y disponer de fondos para...

Análisis estático: por qué se usa (tan poco)

Después de leer sobre qué es el análisis estático, seguro que se os ha quedado cara de “¿dónde está el truco?”. Por que si hay una forma automática de encontrar todos esos bugs tan molestos, ¿cómo es que no se usa siempre? Resumiendo, podríamos decir que hay dos tipos de razones. Por un lado, están  las técnicas: es difícil construir una buena herramienta de análisis estático. Por otro lado, también está el factor humano: deben ser sencillas de usar e integrarse fácilmente al flujo de desarrollo de una empresa concreta. Empecemos por las cuestiones técnicas. Un artículo muy interesante sobre el tema es “A Few Billion Lines of Code Later: Using Static Analysis to Find Bugs in the Real World“, publicado en 2010 en la revista Communications of the ACM. El artículo explica, en primera persona, la experiencia de la empresa Coverity al aplicar sus herramientas de análisis estático en un contexto real. El primer problema que se encontraban al aplicar su herramienta en un nuevo cliente era de lo más gracioso: cómo encontrar el código fuente. Un ingeniero suele saber qué instrucciones  (o botones, si se usa una GUI) usar para compilar el código pero… ¿cómo decirle a una herramienta dónde encontrarlo? ¿En el disco duro? ¿En un sistema de control de versiones? ¿En un servidor de integración continua? En aplicaciones sencillas es muy fácil, pero en productos complejos el proceso de compilación puede llegar a ser muy complejo. Por ejemplo, parte del código puede ser generado a partir de un fichero de configuración. En esta situación, no basta con decirle a la herramienta “el código está en este directorio”. Ojalá. Otro problema divertido es que, como dicen los autores con...

Análisis estático: deja que tu ordenador encuentre el bug

Veamos qué os sugieren estas palabras: división por cero, deadlock, segmentation fault, memory leak, NullPointerException, buffer overflow, … Me imagino que os sugieren unas cuantas horas delante del debugger, muchos cafés y diversas palabras malsonantes. Estos son algunos de los errores software más frecuentes a bajo nivel. Es decir, no estamos hablando de un error en la lógica de negocio, como puede ser calcular mal el importe de una factura. Al ser de bajo nivel, estos errores suelen tener causas muy claras, cómo haberse olvidado una línea de código (el típico free() que te dejas en la última línea de la función) o haberla escrito en un lugar inapropiado (dentro de un if-then-else en lugar de hacerlo después). Esta sencillez hace que sea factible diagnosticar dichos errores de forma automática antes de ejecutar el programa. Precisamente este el objetivo de las herramientas de análisis estático.   Una herramienta de análisis estático busca defectos en un programa a partir del código fuente sin necesidad de ejecutarlo. De aquí viene el término “estático”, para diferenciarlo de métodos “dinámicos” como el testing que necesitan ejecutar el código. De hecho, el compilador ya intenta realizar algunas comprobaciones estáticas, como puede ser la concordancia de tipos. Pero un analizador estático intenta ir mucho más allá de donde llega el compilador y encontrar problemas más sofisticados. Un analizador estático puede buscar diferentes tipos de errores, ya sean predefinidos como los anteriores o bien propiedades definidas por el usuario. Simplificando mucho, el análisis empieza construyendo el grafo que describe el flujo de ejecución dentro de una función (control flow graph o CFG) y el grafo que modela las llamadas entre diferentes funciones (call graph). A partir de aquí, el...