Una de las cosas interesantes -y más frustrantes- que he notado a lo largo de los años es la diferencia entre cómo los ingenieros de redes y los desarrolladores de aplicação ven las aplicaciones. Hemos visto esto en la forma en que se representan las aplicações en los diagramas de red y, a la inversa, en la forma en que se muestran las redes en los diagramas de arquitectura de aplicação .
No hace falta decir que cada uno tiene una visión muy simplista del otro.
Esto también es válido para la seguridad, cuyo papel en la protección no sólo de las redes y las aplicações , sino del propio negocio, se ha vuelto primordial. Es importante que los equipos de seguridad vayan más allá de los diagramas arquitectónicos típicos para comprender realmente las aplicações. Un porcentaje significativo de ataques (exitosos) se ejecutan en la capa de aplicação . Cuanto más tiempo no logremos reconocer las características únicas de los distintos tipos de aplicações, más tiempo seguirán siendo vulnerables esas aplicações .
La discusión de hoy se centrará en las SPA. Se trata de " Aplicações de una sola página" para aquellos que se preguntan qué significa este TLA en particular.
Una aplicação de página única es precisamente eso: una única página web que sirve como marco para todas las tareas relacionadas con la aplicación. Esta arquitectura nos remonta a la época de la Web 2.0 y al surgimiento de AJAX como método para “refrescar” elementos DOM (Modelo de objetos de documento) individuales en lugar de recargar la página entera. El rendimiento se mejoró enormemente con esta técnica y es precursora de la aplicação moderna de página única.
Estas aplicaciones reflejan más de cerca el comportamiento de una aplicación móvil, donde la interfaz de usuario del cliente se carga cuando se abre por primera vez y la comunicación con el servidor involucra solo datos. Esto significa que cada llamada al servidor no contiene nada más que datos y cualquier cambio en la interfaz de usuario se produce en el cliente. Esto reduce drásticamente la cantidad de datos que se envían de un lado a otro y, como puedes imaginar, significa un mejor rendimiento. Este tipo de aplicaciones utilizan API para intercambiar datos.
En general, hemos estado operando bajo el supuesto de que la mayoría de esas API se implementan utilizando principios REST. Esto significa que cada objeto (generalmente considerado como vinculado a un solo elemento de la interfaz de usuario) tiene su propia API que puede invocarse para ejecutar transacciones CRUD (crear, leer, actualizar y eliminar). Desde una perspectiva de seguridad, eso hace que las cosas sean un poco más fáciles porque puedes esperar datos en formatos específicos para una llamada API (URI) determinada. Los datos enviados a "/update/product/123" siempre serán el mismo objeto serializado, mientras que los datos enviados a "/delete/order/4433" serán un objeto serializado diferente. Esto significa que las prácticas tradicionales de vincular políticas específicas a URI específicos se pueden utilizar para proteger esa API.
Ahora bien, las SPA pueden –o no– seguir este patrón. Las prácticas emergentes en torno a las SPA pueden usar y de hecho usan la misma API para realizar transacciones, así como un mapeo de función a URI más tradicional. Con un único patrón URI SPA, el URI no cambia, pero los objetos serializados enviados entre el servidor y el servidor sí lo hacen.
Esto recuerda a las transacciones SOA/XML, en las que se utilizaría un único punto final (URI) para invocar múltiples funciones. La función (punto final) objetivo estaba contenida dentro de los datos XML serializados o, a veces, insertada en un encabezado HTTP personalizado. Este modelo condujo a la necesidad de contar con puertas de enlace SOA/XML que fueran responsables de recibir la solicitud y determinar qué función se estaba invocando antes de enrutarla al punto final correcto (servidor).
Con las SPA, es posible que tengas que lidiar con múltiples llamadas API o solo con unas pocas. En todos los casos, es probable que se encuentre ante la necesidad de proteger los datos en algún formato (quizás XML, más probablemente JSON). Esto significa que debes ser consciente de que el contenido conlleva riesgos. Debido a que algunos datos se pueden usar para generar dinámicamente elementos de UI (o manipular de otro modo el DOM en el cliente), es importante buscar y destruir código potencialmente malicioso en cada envío.
Lamentablemente, si se utiliza un único URI para intercambiar datos para distintas funciones, la práctica tradicional de asociar políticas a los URI no funcionará. De hecho, eso puede violar la seguridad porque dichas políticas a menudo están entrenadas para esperar formatos de carga útil específicos. Las puertas de enlace API también suelen vincular políticas (de enrutamiento, medición y acceso) a una URI específica. Esto significa que usar solo unas pocas URI (llamadas API) para gestionar muchas más funciones con distintos formatos de datos puede vulnerar la seguridad existente.
Este es un ejemplo de por qué es cada vez más importante que la seguridad y el desarrollo (no DevOps, sino los desarrolladores) trabajen más de cerca desde la primera línea de código hasta la implementación. Hay cosas que los desarrolladores pueden hacer desde el principio para facilitar que la seguridad implemente las protecciones adecuadas, como insertar un encabezado HTTP con un indicador que permita ejecutar la política correcta. Algo tan simple como "X-Code: 'order'" enriquecería las solicitudes de manera tal que las soluciones de seguridad podrían identificar (y posteriormente escanear) los datos en busca de posibles vulnerabilidades.
Desde el punto de vista arquitectónico, esto puede requerir un proxy L7 inteligente que pueda extraer el código y reescribir el URI antes de enrutar la solicitud a la solución de seguridad adecuada (WAF, API Gateway, etc.). Este enfoque también funciona si el proxy L7 inteligente puede hablar el lenguaje de formato de datos, como JSON, y los desarrolladores incluyen en cada intercambio algún código o nombre de punto final que se pueda usar para reescribir y enrutar al lugar correcto.
Lo óptimo sería incorporar la seguridad de la capa de aplicação en la propia aplicación para lograr el mejor equilibrio entre rendimiento y seguridad. Sin embargo, eso no siempre es posible y a veces se requieren soluciones arquitectónicas creativas para lograr el objetivo de seguridad.
En términos generales, los cambios en la forma en que los desarrolladores distribuyen diversas responsabilidades entre el cliente y el servidor tienen un impacto significativo en la forma en que la infraestructura del servicio de aplicação interactúa con las solicitudes y respuestas posteriores. Es importante que los equipos de seguridad, desarrollo e infraestructura de servicios de aplicação participen en todo el ciclo de vida del desarrollo de software (SDLC). Implementar una solución arquitectónica también requiere tiempo. Si lo deja "para el final", estará sumando días, o semanas, o incluso meses, de tiempo adicional para comercializarlo. O vas a comercializar sin servicios de seguridad, lo que tiene su propio conjunto de riesgos (y consecuencias).
La colaboración desde el primer día de desarrollo es la mejor (y más rápida) manera de garantizar que las aplicaciones estén disponibles, sean rápidas y seguras cuando entren en producción.