Lo he visto en demasiadas ocasiones: una aplicación es concebida inicialmente para realizar un conjunto reducido de tareas, pero, con el tiempo, se va tratando de incluir más y más funcionalidad. Lo que debería ser un éxito (se pide nueva funcionalidad porque lo anterior funciona y es de utilidad) se termina convirtiendo en una auténtica patata caliente imposible de mantener y para la que cualquier nuevo cambio cuesta más y más esfuerzo (y dinero) en introducirse.

También lo he visto (y sufrido) demasiadas veces: los responsables de esas aplicaciones son reacios a reconocer el problema y suelen echar balones fuera y mantenerse dentro de cierto caos antes de asumir profesionalmente que se ha alcanzado un punto crítico en el que hay que tomar decisiones desagradables.

El resultado es siempre el mismo: después de mucha frustración, se llega inevitablemente a la conclusión de que hay que rehacer partes completas de la aplicación cuando no tirarla a la basura completamente y comenzar desde cero.

No podemos perder la perspectiva: si se trata de un proyecto con cierto carácter lúdico, un repositorio que apenas mantienes en Github o Codeplex, bien, no pasa nada, salvo el tiempo que se haya podido perder, pero si se trata de un proyecto empresarial, todo lo anterior se traduce en costes dolorosos y, seguramente, un equipo frustrado por trabajar en una aplicación difícil.

Este es un mantra que conviene no olvidar nunca: todo software requerirá de cambios inevitablemente (y el fundamento del enfoque ágil). Si no se diseña para admitirlos, entonces nos encontraremos tarde o temprano con una aplicación corrupta y el escenario descrito párrafos más arriba.

La buena noticia es que se puede evitar, trabajando desde el inicio del proyecto en la línea correcta.

Pero, ¿por qué llega a corromperse una aplicación con el paso del tiempo a medida que la hacemos cambiar? A continuación enumero una lista de algunas de la razones:

  • Una aplicación es concebida inicialmente como simple o pequeña y se le obliga a crecer de forma muy rápida y descontrolada.
  • No existe metodología a la hora de ir introduciendo nuevos cambios: los requisitos llegan de un día para otro, se vuelve atrás con frecuencia, no hay planificación y cultura de testing o validación de la aplicación antes de ser entregada, abonando el terreno para el caos.
  • Los requisitos no son claros: la traducción de los requisitos de negocio a los requisitos técnicos no se realiza con exactitud y la suficiente comprensión. El resultado es que se implementa funcionalidad que no es exactamente la que se quería, produciendo una cascada de cambios y, posiblemente, dejando código muerto y obsoleto a medida que eso ocurre, ensuciando la solución.
  • Se utiliza una dispersión de tecnologías que dificulta la evolución de la aplicación. Para programar bien y de forma mantenible, hay que conocer bien las librerías y frameworks que se utilizan; un exceso de estos en la misma aplicación provoca confusión y es más difícil de llevar. Además, si se usan librerías complejas, esto ofuscará la solución.
  • No se dedica tiempo a mejorar lo que ya existe, aunque funcione. El desarrollo de software es en cierta medida incremental: construimos nueva funcionalidad sobre lo ya existente o del mismo modo que lo que ya existe. Hay que tener siempre la actitud de mejorar continuamente lo que ya hay.
  • Se intenta mantener código obsoleto, mal diseñado, mal probado, a toda costa. A veces cuesta trabajo eliminar partes de la aplicación porque recordamos el esfuerzo que nos llevó hacerlas, o por simple pereza, pero arrastrar algo que no está del todo bien es perjudicial: podemos decir que lo que eliminamos, en realidad, nos sirvió para aprender a hacerlo mejor.
  • No se tiene en cuenta que no solo se mejora el código en sí, también el diseño y la organización del proyecto.
  • No se siguen prácticas de código limpio y de refactoring de forma continuada.
  • El proyecto no tiene tests o la batería de tests es insuficiente con una cobertura de código baja. Esto provoca que no sepamos cuanto antes qué bugs introducimos al hacer cambios: cuanto antes se detecte un bug, más fácil y sencillo será corregirlo. Además, incluir tests obliga a diseñar la aplicación con mejor estructura (software testeable), alejándonos de enfoques monolíticos y rígidos.
  • El diseño (si es que existe) es pobre.
  • Y, por supuesto, ocurre parte o todo lo que describro en El Libro Negro del Programador

​Lo bien o lo mal que hagamos todo lo anterior, hará que lleguemos antes o después a la barrera de inmantenibilidad, tal y como describe la curva o Ley de Boehm, que viene a indicar el coste incremental de corregir errores desde una fase temprana del proyecto o en una fase tardía (cuando ya el software es... demasiado corrupto):

Boehm's Law

Nota: este artículo es es un resumen y forma parte del proyecto en desarrollo El Libro Práctico del Programador Ágil. Lanzamiento en julio 2018.


 

Software security

Hace unos meses leíamos sorprendidos la noticia de que un grupo de estudiantes francés había descubierto miles de bases de datos MongoDB con acceso público y abiertas, no por alguna vulnerabilidad en ese engine de base de datos, sino por malas prácticas de quienes las habían implantado. Terrorífico si se piensa por un momento; puede parecer anecdótico pero el fondo de la cuestión es que la información de esas bases de datos podrían poner en situación de vulnerabilidad a personas, instituciones e incluso países. Sin llegar a exagerar, ese caso probablemente no sea más que un gota en el océano.

Admitámoslo: cuando se trabaja desarrollando proyectos, casi siempre terminan entregándose con presión de tiempo y dejando una larga estela de TO-DOs y de elementos que se podrían mejorar. Es más, pocos clientes, sobre todo si son de ese tipo que no entienden demasiado de tecnología porque su negocio o actividad es otro, ignoran cómo evaluar la calidad de lo que se les entrega: mientras funcione y lo que ven les guste, no habrá problemas, todos contentos, nosotros hemos entregado un proyecto, la compañía lo habrá cobrado y a otra cosa.

Cuando hablamos de software, hablamos de un medio que permite que otras actividades funcionen: la gestión documental de una compañía, el blog de un freelance, al firmware de una lavadora o un sistema Scada que gestiona una central térmica.

Sin embargo, ¿existe realmente interés por encarar la seguridad en el contexto de cualquier proyecto software sea del tipo que sea? No estoy hablando de software para aeronaves, plantas nucleares, etc., sino aplicaciones de cualquier tipo realizado por cualquier empresa para clientes no excepcionales (que, por otra parte, intentan pagar lo menos posible).

Esto es lo que quiero decir: la seguridad informática apenas es un aspecto relevante para la mayoría de desarolladores de software, y es así no porque ignoremos técnicamente cómo afrontar esos temas, sino porque en general no existe una cultura tecnológica extraordinariamente preocupada por exigir consumir software con todos los estándares de seguridad. La ciberseguridad sigue siendo más un término de películas de ficción que una auténtica preocupación masiva en toda nuestra industria.

Tanto si se trata de un simple proyecto que de ser vulnerado puede tener poca o ninguna repercusión, hay muchos otros proyectos para los que cualquier incidencia de seguridad puede ser un auténtico problema: desde la pérdida de horas de trabajo y una enorme frustración para la gente afectada hasta la seguridad física de personas e instalaciones. Y no exagero, en absoluto: por poner un ejemplo, uno de los productos que comercializamos en la compañía para la que trabajo puede dejar literalmente sin luz a miles de abonados de compañías eléctricas. ¿Y si alguno depende de un soporte vital? Es un tema bastante serio que conviene no frivolizar.

La seguridad es importante, extraordinariamente importante, sobre todo en un momento en que toda nuestra economía no sólo es adicta al petróleo sino que también depende de la tecnología para seguir funcionando. Para muchas plataformas, una hora sin funcionar puede significar mucho dinero (aparte de dar una imagen poco profesional), pero también para una pequeña web de una empresa familiar puede suponer muchas horas perdidas para resolver el problema.

Digo yo que para tratar mejor el tema de la seguridad en nuestros trabajos debemos tener también cierta faceta de hackers y actuar como pentesters.

Mr RobotNo hace falta pensar en la seguridad como se plantea en series como MrRobot, no es un tema que vaya de super-hackers con problemas de socialización y de una subcultura de frikies. La seguridad en software está también en nuestro día a día, sea cual sea el tipo de software al que nos dediquemos, no importa las plataformas que usemos: debe formar parte del roadmap de cualquier desarrollo en el que trabajamos.

Pero, ¿cómo? Es cierto que los mismos responsables de proyectos pueden frivolizar sobre este tipo de cuestiones, lo pueden ver más como un coste que como un elemento de calidad diferenciador. Del mismo modo, en cualquier actividad profesional hay que minimizar los riesgos, por tanto, como tareas de desarrollo hay que incluir algún tipo de aseguramiento de la seguridad, tanto a nivel de diseño, configuración de la plataforma en la que nos basemos y también a nivel de despliegue, y, lógicamente, el cliente debe ver ese trabajo como una aportación positiva al proyecto (y por tanto estar de acuerdo y pagar por él).

¿Será un buen momento para diferenciarse profesionalmente como desarrollador experto en seguridad? Desde luego el tema da para mucho.

Lejos de declaraciones grandilocuentes, algunos sencillos ejemplos que podemos tener en cuenta con relativamente poco esfuerzo:

  • Se si usa cualquier repositorio de datos con información sensible, ésta se debe guardar encriptada.
  • Las contraseñas para acceder a middlewares o servicios externos deben ser fuertes, como las security keys que se usan en Amazon o Azure para acceder a servicios en la nube.
  • Si se usa un fichero con contraseñas de acceso de algún tipo, tenemos que garantizar que este no esté accesible una vez desplegado el proyecto (cosa obvia) y, por qué no, pensar también en encriptar el mismo fichero.
  • Si se tiene un cliente web, las validaciones de datos se deben hacer tanto en cliente como en servidor.
  • Cualquier infraestructura software IT que se utilice (servidores web, protocolos, sistemas operativos, bases de datos), se debe revisar en producción y garantizar que estén correctamente configuradas.
  • Y un larguísimo etc...

Por otra parte, habrá clientes a los que les gustará muchísimo ver un anexo sobre seguridad en la propuesta del proyecto. En mi opinión, una empresa que provee software y hace hincapié especialmente en la seguridad de sus desarrollos, además de necesario, se debe percibir como de mayor calidad, por lo que puede ser un argumento diferenciador con respecto a los competidores.

La seguridad en software tiene muchas vertientes; es un tema tremendamente extenso. Como simple perla, para cualquier aplicación web:

  • ¿Aguantaría un ataque DDoS (ataque por denegación de servicio)?
  • ¿Incorpora filtros XSS (cross-site scripting) y evita Sql Injection?
  • ¿Tiene en cuenta el servidor web, sea el que sea, la vulnerabilidad http pollution?
  • ¿Está el servidor web configurado correctamente para ocultar la cabecera "X-Powered-By" o tiene implantado el mecanismo HPKP (http public key pinning)?
  • ¿Implementa la táctica frameguard?
  • ¿Los formularios incorporan el token CSRF (cross site request forgery)?
  • Y aquí también otro larguísimo etc...

¿Ejjj, cómo? Yo no me considero experto en seguridad, ni mucho menos, pero es un tema que cada vez me interesa muchísimo más; si desarrollas aplicaciones web y los conceptos anteriores (cogidos al azar de entre muchos otros) te suenan literalmente a chino, ve pidiendo formación a los Reyes Magos del 2016 o un buen lote de libros para mejorar en ese aspecto.

Es cierto que ser absolutamente exhaustivos con todas las cosas a securizar será una labor extraordinaria, pero, al menos, se podría incluir un checklist en cada proyecto que asegure que se cumplen los elementos de seguridad imprescindibles.

Por cierto, y hablando de seguridad ¿por qué los hackers, al menos ciertos hackers mediáticos, aparecen siempre con un aire desaliñado, gorritas, camisetas y con barba de varios días? Curioso... :-)

Es ya recurrente en mis posts el insistir sobre el tema de la calidad en nuestro trabajo como único recurso para crearnos de verdad un buen currículum y una buena carta de presentación.

Aunque la calidad no deja de ser un concepto demasiado interpretable, en software viene a ser equivalente a que el sistema o aplicación que se entrega funciona según los requerimientos del cliente y, por supuesto, que no tenga fallos, que sea fácil de mantener, evolucionable, etc. Esto a mí me parece evidente aunque no siempre se tiene en cuenta en el día a día de un desarrollador.

Ahora bien, no siempre se ve claramente la relación entre la gestión de un proyecto software y el resultado final de este. En mi opinión no sólo es importante sino también determinante.

Desarrollar software no es sentarte ante un ordenador y pasarlo bien escribiendo líneas de código (bueno, también, pero lo que quiero decir es que no sólo es eso). Cuando tenemos que entregar algo para una fecha determinada, hay que planificar, cuando trabajamos en equipo las tareas hay que repartirlas coherentemente, o sea, hay que gestionar la carga de trabajo, cuando se ponen las bases de un nuevo sistema hay que tomar decisiones de diseño y antes de todo eso hay que tomar, interpretar y traducir al lenguaje del desarrollador las especificaciones de un cliente que en ocasiones no tiene del todo claro lo que quiere o necesita.

Todos esos puntos no son más que la punta del iceberg y absolutamente todos están relacionados con la gestión de un proyecto software, sin hablar de la responsabilidad que conlleva ya que ciertas malas decisiones pueden tener efectos catastróficos.

Ingenuamente hay quien piensa que eso de gestionar consiste en ordenar y mandar lo que otros tienen que hacer para sentarnos cómodamente a esperar que las cosas se hagan solas porque sí. Bajo esa concepción, el desastre de un proyecto software está asegurado.

Aunque hay tantas particularidades como proyectos y puesto que un proyecto de software tiene su propia idiosincrasia, básicamente cuando alguien se enfrenta a la gestión por primera vez no tiene una idea clara de lo que se espera de él.

Se aprende por mucha prueba y error (y estos a veces se pagan caro), pero, entre las habilidades esenciales que debe contar un buen gestor software están en mi opinión las siguientes:

  • Saber dar prioridad a la funcionalidad que se debe implementar en cada momento.
  • Mantener un equipo de trabajo coherente sabiendo cuáles son los déficits y mejores habilidades de cada miembro del equipo.
  • Potenciar las capacidades de cada miembro del equipo presionando (que no ahogando) lo suficiente de modo que una meta se convierta en un aliciente.
  • Crear una planificación con el tiempo suficiente como para compartirla con el equipo.
  • Nunca, absolutamente nunca, romper esa planificación (salvo ocasiones muy puntuales y con razones de peso), es decir, los desarrolladores debemos saber en cada momento qué tareas tenemos que hacer a un tiempo vista.
  • Mantener la suficiente paz de trabajo para que los desarroladores puedan estar concentrados de la mejor manera posible, lo que implica a veces pararle los pies a un cliente díscolo o discutir incluso con tu propio jefe (el jefe del gestor, digo). En ocasiones también supone no compartir esas ansiedades o inseguridades relacionadas con tu propia responsabilidad como gestor en donde existen otro tipo de problemas en relación al resto de la compañía que pueden no ser bien entendidas por los desarrolladores que diriges.
  • Mantener al cliente a raya, esto es, vigilar que este no cambia de opinión continuamente y que cualquier cambio en la especificación no está fuera de presupuesto, si es que se gestiona también el proyecto a este nivel.
  • Comprobar que se utilizan las herramientas elegidas y los flujos de trabajo definidos.
  • Conseguir que los desarrolladores trabajen en las mejores condiciones posibles, buenos equipos, formación adecuada, etc.
  • Comprobar que se mantiene la metodología de desarrollo elegida.

Y un larguísimo etcétera...

Cuando un proyecto software falla, el único responsable es el gestor del mismo, no hay más. Pocas cosas hay realmente que no se vean venir y parte de la responsabilidad de un gestor de un proyecto software es también gestionar riesgos, de incumplimiento, de calidad de lo entregado, etc. Si la cosa al final se tuerce, entonces tener la actitud valiente de reconocer los errores, aprender de ellos y asumir la responsabilidad. Tampoco es que te vayan a crucificar, pero si en momentos así somos inteligentes, aprenderemos mucho de los errores cometidos.

Lamentablemente no son pocos los casos en los que la única forma de ascenso laboral consiste en conseguir un puesto de gestión para el que quizá no se tienen las aptitudes adecuadas.

Se confunde en ocasiones un puesto de gestión (la verdad, qué mal me suena esto) con estar en una silla desde la que la gente hace lo que uno diga, cuando la realidad es que no tiene nada que ver con eso:

La responsabilidad de un gestor es gestionar recursos técnicos, humanos, formativos, etc. para conseguir que un producto se entregue correctamente. No tiene nada que ver con ser respetado con un autoritarismo medieval, sino con ganarte una cierta autoridad para que tus decisiones sean respetadas porque has demostrado tu experiencia y tus aciertos así como tu aceptación de los errores (sin colgarle a otros el muerto, cosa lamentablemente bastante común).

Hay muchos proyectos software que terminan con un éxito maravilloso gracias a la pericia de los desarrolladores del equipo en quienes un gestor incompetente ha delegado gran parte de sus responsabilidades; cuando esto ocurre, les recomiendo a estos desarrolladores que busquen otro jefe o incluso que cambien de compañía, ya que seguramente estarán mucho menos recompensados económicamente que su gestor, jefe, coordinador o lo que sea, injusto, pero esta situación se vive cada día y en todo tipo de compañías.

Del mismo modo que se busca un tipo de empresa para la que trabajar, ¿por qué no también buscar rodearte de un ambiente creativo con gente competente que te permita avanzar todavía más en tu desarrollo profesional? ¿Estás rodeado de gente a la que criticas y con la que tienes que trabajar, que consideras incompetentes y que no te aportan nada salvo algunos ji-ji y ja-ja en la hora del café? Pues toma nota, estás perdiendo el tiempo.

Si eres desarrollador y quieres gestionar proyectos software, busca trabajar con un buen gestor que te transmita su experiencia, lee libros al respecto y déjale claro de paso que estás preparado para asumir nuevas responsabilidades (pero ojo, no de palabra, sino con un trabajo de calidad en tu día a día).

Un gestor de proyectos aprende continuamente (el que crea que ya lo sabe todo estará fuera del mercado en unos años) y los desarrolladores con los que trabaja deben también ser capaces de aprender de él todo lo posible para el mejor desempeño de su profesión.

Si trabajamos como freelance casi todo lo anterior sigue siendo igualmente válido, ya que en ese caso seremos gestores de nuestro propio trabajo y al mismo tiempo seremos desarrolladores de un proyecto que también se tiene que hacer en orden y con calidad.

¿Por qué leer El Libro Negro del Programador?

Adquirir desde:
Amazon (kindle eBook / papel)
CreateSpace (papel)
PayHip (epub / mobi / pdf)

El libro negro del programador.com
Segunda Edición - 2017

Archivo

Trabajo en...

Mis novelas...