Patrones orientados a aspectos para hacer aplicaciones seguras

Tamaño: px
Comenzar la demostración a partir de la página:

Download "Patrones orientados a aspectos para hacer aplicaciones seguras"

Transcripción

1 Patrones orientados a aspectos para hacer aplicaciones seguras Vladimir Emiliano Moreira Rocha Universidade de São Paulo Departamento de Ciência da Computação São Paulo, Brasil vmoreira@ime.usp.br and Christian Danniel Paz Trillo Universidade de São Paulo Departamento de Ciência da Computação São Paulo, Brasil cpaz@ime.usp.br Abstract Nowadays, one of the main objectives when developing software systems is to make them secure. Often, systems are designed and implemented without security in mind since initial development phases, producing design changes and bigger costs. There are object-oriented solutions to deal with this problem, but they lead to code reuse problems, because of intruder code inside application classes. This occurs since security is a traversal functionality, which is not effectively handled with object-oriented approaches. Aspect-oriented programming complements object-oriented programming to treat this kind of problems. This paper presents aspect-oriented patterns focused on secure applications, so its inclusion do not affect the system architecture. Keywords: Aspect-Oriented Programming, Software Security, Architectural Patterns Resumen Hoy en día, uno de los objetivos primordiales al desarrollar sistemas, es que sean seguros. Muchas veces los sistemas son diseñados e implementados sin tener en cuenta la seguridad desde las fases iniciales, lo que genera cambios en el diseño y mayores costos. Existen soluciones propuestas desde el punto de vista de la orientación a objetos, pero que aún así conllevan a problemas de reutilización debido a código intruso de seguridad, dentro de las clases de la aplicación. Esto se debe a que la seguridad es una funcionalidad transversal con la cual la orientación a objetos no puede lidar eficientemente. La orientación a aspectos surge como complemento a la orientación a objetos para tratar ese tipo de problemas. Este trabajo presenta patrones orientados a aspectos enfocados en dar seguridad a las aplicaciones, tal que su incorporación no influya en la arquitectura del sistema. Palabras claves: Orientación a aspectos, Seguridad de Software, Patrones Arquitecturales. 1 Introducción En la actualidad, la mayoría de aplicaciones requieren implementar ciertas características de seguridad, debido a la gran cantidad de intromisiones no intencionales e intencionales. Sin embargo, frecuentemente los sistemas son diseñados e implementados, sin tener en mente la seguridad. Dar seguridad a un sistema orientado a objetos, implica modificar las clases a las cuales se desea implementar esta funcionalidad, y con esto, el código asociado a la seguridad queda disperso en el sistema. Realizar modificaciones a características de seguridad por tanto, involucraría hacer cambios en diversos puntos del código. En [6] fueron presentados diversos patrones orientados a objetos que tratan un conjunto amplio de problemas de seguridad, que intenta extraer las características de seguridad a clases especializadas. Sin embargo, el problema de fondo, es que la seguridad comunmente es una funcionalidad transversal a la aplicación. Cuando una funcionalidad transversal es tratada con programación orientada a objetos, difícilmente es implementada con una alta cohesión. La programación orientada a aspectos propone formas de exponer y desarrollar funcionalidades transversales en las distintas etapas de un proyecto de forma que exista alta cohesión en la solución.

2 En este trabajo presentamos algunos problemas típicos en seguridad, como los presentados en [6], y las soluciones a los mismos con orientación a aspectos. Para cada patrón, será presentado el problema a través de un escenario ejemplo, la solución, las consecuencias de la aplicación del patrón y algunos patrones orientados a objetos relacionados a la solución del problema. En la Sección 2 presentamos la Programación Orientada a Aspectos como un complemento a la Programación Orientada a Objetos y los principales componentes para su implementación. Las siguientes dos secciones muestran un problema de implementación de seguridad en una aplicación y su respectiva solución orientada a aspectos. La Sección 3 muestra el patrón para control de políticas, que ayuda en el control de acceso a funcionalidades por parte de usuarios y el control de accesos indebidos. El patrón interfaz segura, que facilita la implementación de interacción entre sistemas, es presentado en la Sección 4. Finalmente, las conclusiones y trabajos futuros son presentados en la Sección 5. 2 Programación Orientada a Aspectos 2.1 Perspectiva General Los lenguajes de programación han ido evolucionando desde la codificación a nivel de máquina (código Ensamblador) hasta lo más común hoy en día que es la orientación a objetos. En cada uno de estos avances se ha tratado de entregar a los desarrolladores una mejoria en la identificación, encapsulamiento y manipulación de entidades que son propias de una funcionalidad del sistema. Las tecnologías involucradas en la orientación a objetos, tales como: metodologías, herramientas de análisis y diseño, patrones, etc. han reducido en gran medida los problemas de mantenimiento y codificación de sistemas de mediana y gran complejidad. A pesar de estas mejorías, la orientación a objetos tiene algunas limitaciones como el encapsulamiento de una funcionalidad del sistema que está dispersa por varias clases. Estas funcionalidades pueden ser de diversos tipos como: seguridad, calidad de servicio, reglas de negocios, sincronización de métodos, etc. Estas funcionalidades son llamadas Funcionalidades Tranversales. 2.2 Funcionalidades Tranversales Definimos como funcionalidad tranversal a una funcionalidad del sistema (por ejemplo un caso de uso en notación UML) que se interseca con otra funcionalidad y que no puede separarse en unidades modulares. Por ejemplo una funcionalidad transversal es el logging 1 de todas las operaciones de transacción(otra funcionalidad) de un sistema de finanzas de una empresa. 2.3 Programación Orientada a Aspectos Como sabemos de la orientación a objetos, sólo una funcionalidad puede estar encapsulada en una clase para que tenga cohesión, pero esto es muy difícil de obtener en la mayoría de los sistemas complejos. La orientación a aspectos[2] es una nueva tecnología que trata el problema de las funcionalidades transversales encapsulando el comportamiento que afecta a distintas clases en unidades modulares llamadas Aspectos. Como resultado de esto se tiene un módulo coheso con un comportamiento igual al de una clase en la Orientación a objetos, con atributos, procedimientos, funciones, etc. Es importante destacar que la programación orientada a aspectos es un complemento a la programación orientada a objetos y en ningún caso la sustituye. En la programación orientada a aspectos, existen cuatro componentes básicos e indispensables [3]: Join-Point: Es el responsable de definir los puntos de enlace donde será agregado el comportamiento a ser ejecutado. Estos enlaces son puntos bien definidos del programa, como: constructores de clases, métodos, llamadas a métodos, excepciones, etc. Pointcut: Es el que modela la estructura de la funcionalidad transversal. Para esto contiene una selección de Join-Point basados en un criterio de operadores lógicos. Advice: Responsable de agregar el comportamiento a ser ejecutado cuando se intercepta un punto determinado del programa definido en el Pointcut. Aspect: Unidad básica de la Programación orientada a Aspectos que contiene las tres construcciones básicas antes mencionadas. Tiene el mismo comportamiento que una clase y es encargado de encapsular las funcionalidades tranversales dispersas en el sistema. 1 Logging es la funcionalidad de guardar en algún medio, archivos o base de datos, información sobre lo que está sucediendo en el sistema. 2

3 2.4 Ejemplo Veamos ahora un ejemplo que clarifique lo descrito. Supongamos que tenemos un sistema de compras on-line (ver Figura 1) al cuál se le desea agregar las siguientes funcionalidades: Lista de los artículos más visitados del sistema. Lista de los artículos más comprados del sistema. Figura 1: Ejemplo de Sistema de Compras Online. Diagrama de Clases Una posible solución orientada a objetos consiste en crear una clase Log que sea la responsable de obtener la información necesaria para cumplir estos requisitos. Pero esto requerirá modificaciones en las clases CarroCompras e Item que tendrán que hacer referencia a la nueva clase creada. Como vemos, esta funcionalidad de logging se dispersa por diversas clases (CarroCompras e Item) y genera un problema a la reutilización y encapsulamiento de las mismas. La solución en orientación a aspectos simplifica este problema. Primero, creamos los puntos de enlace (Join-Point) que tendrá el aspecto. En este caso serán los métodos: CarroCompras.compra() Item.visita(idItem) Con esto, en cualquier parte del programa en que se haga referencia a estos métodos se ejecutará el aspecto. Luego generamos el Pointcut para cada funcionalidad. pointcut visitados() : call(item Item.visita(idItem)) pointcut comprados() : call(bool CarroCompras.compra()) Ahora insertamos el comportamiento que deben tener las funcionalidades, esto es, el Advice. after() : visitados() //hacer logging de los items visitados que actualiza los contadores after() : comprados() //hacer logging de los items comprados que actualiza los contadores Finalmente lo encapsulamos todo dentro del aspecto. 3

4 aspect Logging pointcut visitados() : call(item Item.visita(idItem)) pointcut comprados() : call(bool CarroCompras.compra()) after() : visitados() //hacer logging de los items visitados que actualiza los contadores after() : comprados() //hacer logging de los items comprados que actualiza los contadores Como vemos, ahora cualquier cambio referente a loggingpodrá hacerse directamente en el aspecto y no se tendrá que buscar en las clases para verificar si implementan o no dicha funcionalidad. Además, las clases CarroCompras e Item no son afectadas con comportamientos externos a su funcionalidad y por tanto mantienen su cohesión. 3 Patrón: Control de Políticas 3.1 Intención Aplicar las políticas de seguridad para controlar el acceso a funcionalidades de la aplicación y manipular accesos indebidos. 3.2 Aplicabilidad Se tiene un Sistema existente de Control de Pacientes en un hospital, al cual se le debe dar seguridad. Algunas de las características deseadas son: Se desea que sólo el médico del paciente pueda ver su historial. Las búsquedas por pacientes inexistentes o pacientes de otros médicos deben ser registradas por auditoría. En el acceso del médico al sistema, no puede equivocarse más de 3 veces al poner su contraseña. Sólo el usuario registrado como contacto del paciente puede accesar a la funcionalidad de ver ubicación del paciente. Para solucionar estos requerimientos, se propone modificar el sistema colocando funcionalidad transversal en los métodos afectados, como se ve en la Figura 2, de forma que: El método verhistorialpaciente de la clase Medico es interceptado en el aspecto ControlPoliticas para verificar si el paciente corresponde al médico que hace la consulta, o no existe. El método ingresa es interceptado en el aspecto ControlPoliticas para realizar el conteo de las veces que el médico ingresa una contraseña errónea. El método verubicacionpaciente de la clase Contacto es interceptado en el aspecto ControlPoliticas para verificar si el contacto está registrado como contacto del paciente. 3.3 Estructura de solución Para permitir un adecuado control de políticas mediante el uso de un aspecto que intercepte los métodos a los que se desea aplicar alguna política, puede usarse una estructura como la mostrada en la Figura 3. Las clases que intervienen en la solución son detalladas a continuación. Rol: Representa la función que desempeña el usuario dentro del sistema. Política: Son reglas de seguridad, como errores de usuario y permisos para acceder a funcionalidades. Las políticas van de acuerdo al rol. 4

5 Figura 2: Escenario de ejemplo. Patrón de Control de Políticas. Figura 3: Estructura de solución. Patrón de Control de Políticas. Valor: Guarda valores que serán usados en el control de seguridad de la aplicación. Sesión: Mantiene el estado de seguridad general. Es un repositorio de valores y políticas. La interacción dentro del aspecto de control de políticas es esquematizado en la Figura 4. Cuando el control de políticas es llamado, se verifica si el funcionamiento es adecuado al rol obteniendo los valores actuales (número actual de intentos de ingreso) comparándolo con el valor de la política (número máximo de intentos de ingreso permitidos). En caso de no ser un funcionamiento adecuado se ejecutará el efecto de la política(registro en el log). 5

6 Figura 4: Interacción de las clases de la solución. Patrón de Control de Políticas. 3.4 Consecuencias Las validaciones de acceso y uso de funcionalidades del sistema quedan encapsulados en el aspecto y no dispersos en las clases que contienen esas funcionalidades. Este patrón puede ser aplicado en sistemas existente sin un esquema de seguridad apropiado. Facilita la incorporación o modificación de políticas de seguridad debido al encapsulamiento de las mismas en el aspecto. 3.5 Patrones relacionados Roles[6]: Este patrón indica que se debe agrupar a los usuarios según similaridad en los priviliegios de seguridad que tienen. La clase Rol implementada dentro del aspecto, sigue este patrón, pues en base al rol las políticas deberán ser cargadas. Check Point[6]: La idea es restringir a los usuarios el acceso sólo a las funcionalidades del sistema para las que tienen permiso. Esa es exactamente la idea de una política, restringir las acciones del usuario a sólo aquellas que tiene permiso de ejecutar. Role Based Access Control[4]: Describe la relación entre los conceptos de usuario, grupo y rol. Es decir un usuario pertenece a uno o más grupos y cumple uno o más roles. El rol puede estar asociado tanto al grupo como al usuario directamente. 4 Patrón: Interfaz Segura 4.1 Intención Proporcionar seguridad en la comunicación de las interfaces de la aplicación con otros sistemas. 4.2 Aplicabilidad Existen dos escenarios posibles en que una aplicación puede interactuar con otras, el primer caso se da cuando un sistema ofrece servicios y el otro caso cuando el sistema utiliza servicios de otro sistema Escenario 1: La aplicación ofrece servicios En este escenario la aplicación provee servicios que serán accesados por otros sistemas. Tenemos un sistema de cuentas corrientes de un banco que será accesado por un cajero automático. Se desea encapsular las características propias de la seguridad en la comunicación y encriptar los datos privados de la cuenta a ser enviados por la red. El primer paso para la solución consiste en generar interfaces para los servicios provistos(interfaz CuentaCorriente). Ver Figura 5. En el segundo paso se coloca la capa de Interfaz Segura en las implementaciones de las interfaces generadas en el paso anterior. En esta capa se interceptan los metodos que implementan la interfaz añadiéndole seguridad a la comunicación (encriptación, auditoría, etc.). Ver Figura 6. 6

7 Figura 5: Generación de Interfaces de los servicios provistos. Patrón de Interfaz Segura. Figura 6: Capa de Interfaz Segura. Patrón de Interfaz Segura Escenario 2: La aplicación accesa servicios externos Un sistema externo ofrece servicios a través de una interfaz que, por definición, no tiene implementación. En el primer paso se crea una clase por cada interfaz ofrecida que delega las requisiciones al sistema externo. Estas clases se pueden ver en la Figura 7 y tendrán los mismos métodos que la interfaz a la cual delegan sus llamadas. El segundo paso es equivalente al del escenario 1, interceptando los métodos de las clases generadas en el paso anterior. 7

8 Figura 7: Clases que delegan las requisiciones a las interfaces del sistema externo. Patrón de Interfaz Segura. 4.3 Estructura de solución El aspecto Interfaz Segura será implementado como un patrón decorator [1]. La inicialización de este patrón, consiste en asignar a cada método a ser interceptado los mecanismos de seguridad que le corresponden. En este caso, los mecanismos de seguridad serán los decoradores concretos mostrados en la Figura 8. El método operacion de la clase InterfazSegura iterará sobre la lista de decoradores asociados al método interceptado, llamando al método ejecuta en cada uno de ellos. Figura 8: Estructura de Solución. Patrón de Interfaz Segura. 4.4 Consecuencias El aspecto Interfaz Segura puede ser reutilizado para cualquier control adicional en la comunicación con otro sistema. Se puede añadir de forma dinámica distintos tipos de controles en la comunicación (Patrón Decorator), y por tanto es fácilmente extendible. El aspecto de seguridad en la comunicación queda encapsulado, lo que permite identificar fácilmente los mecanismos que están siendo usados en el control de la comunicación con sistemas externos. La forma de aplicar este patrón para sistemas que usan y/o proveen servicios será similar, pudiéndose aprovechar la estructura interna del aspecto. Si el sistema contiene algún mecanismo de seguridad implementado, la inserción de este patrón se hace difícil puesto que tendrá que extraerse la seguridad para encapsularla en el aspecto. Si el sistema, en cambio, no contiene mecanismos de seguridad en la comunicación, la aplicación del patrón será relativamente simple. 8

9 4.5 Patrones relacionados Enterprise Partner Communication[5]: Patrón gerencial que especifica las características que deben ser contempladas para realizar una comunicación con sistemas de otras compañías. Complementa a Interfaz Segura, pues permite seleccionar las características a implementar como decoradores en el aspecto. Secure Access Layer[6]: Consiste en la creación de una capa alrededor de la aplicación que se encarga de la comunicación con aplicaciones externas. El código de uso de esta capa aún sigue disperso por la aplicación, pero la funcionalidad propia de comunicación externa está en dicha capa. 5 Conclusiones y Trabajos Futuros La programación orientada a aspectos permite encapsular las funcionalidades transversales a la aplicación. Esto permite aumentar la cohesión en las clases. La seguridad de sistemas de software es una funcionalidad transversal. Puede ser extraída de la aplicación hacia un aspecto dándole cohesión al módulo de seguridad como tal. Frecuentemente las funcionalidades implementadas como aspectos pueden ser fácilmente habilitadas o deshabilitadas pues la aplicación no necesita saber que está siendo aspectada. Esta propiedad puede ser de ayuda en periodos de prueba, en que algunas características no están disponibles, algún servidor de autenticación por ejemplo. Hacer implementaciones estándar para los patrones de modo que puedan convertirse en un framework orientado a aspectos extensible y fácilmente enlazable a gran variedad de aplicaciones. Referências [1] R. Johnson E. Gamma, R. Helm and R. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Adisson Wesley, [2] Tzilla Elrad, Robert E. Filman, and Atef Bader. Aspect-oriented programming: Introduction. Commun. ACM, 44(10):29 32, [3] Gregor Kiczales, Erik Hilsdale, Jim Hugunin, Mik Kersten, Jeffrey Palm, and William Griswold. Getting started with AspectJ. Commun. ACM, 44(10):59 65, [4] Razvan Peteanu. Best practices for secure development v4.03. Technical report, Razvan Peteanu, [5] S. Romanosky. Enterprise Security Patterns. In Proceedings of the 7th European Conference on Pattern Languages of Programs (EuroPLoP) 2002, Irsee, Germany, [6] J. Yoder and J. Barcalow. Architectural patterns for enabling application security. In Proceedings of the 4th Conference on Patterns Language of Programming (PLoP 97), volume 2,