| Artículos | 01 OCT 2007

Restricciones de ejecución de código

Tags: Histórico
Cómo restringir la ejecución de código en Java y .Net
Gonzalo Alvarez.
Restringir las acciones del software en función de los permisos del usuario que lo ejecuta no siempre es la mejor solución de seguridad. A veces se necesita restringir lo que el software puede hacer con independencia de la identidad del usuario que lo ejecuta. Las aplicaciones desarrolladas en Java y .Net permiten aplicar restricciones de forma sencilla mediante las directivas de seguridad. En este artículo se explica cómo configurarlas y aplicarlas.

En las dos entregas anteriores se ha explicado cómo firmar código tanto en Java como en .Net. En esta última entrega, que cierra la serie, el lector aprenderá cómo restringir los permisos del código, tanto firmado como sin firmar, una vez comienza a ejecutarse en el sistema. El problema que presenta el código firmado es que por defecto se le conceden todos los permisos. Se trata de una decisión de todo o nada: o se decide denegar completamente el permiso de ejecución al código o se le garantiza, en tal caso con privilegios absolutos, de manera que le estará permitida cualquier acción que el usuario que lo ejecuta pueda realizar. Es decir, el código firmado sólo estaría restringido por los permisos del usuario. Este enfoque de autorización se conoce como seguridad basada en la identidad del usuario.

Restricciones de seguridad: identidad de código vs. identidad de usuario
La forma de seguridad más extendida en los sistemas informáticos se basa en la identidad de usuario. El sistema de seguridad protege una serie de recursos tales como archivos, acceso a internet, memoria, CPU, periféricos, o configuraciones, permitiendo o denegando el acceso a los mismos. Cuando un usuario solicita acceder a un recurso, el sistema debe identificarlo, para lo cual utiliza algún mecanismo de autenticación, como un nombre de usuario y una contraseña. Los mecanismos de autorización configurados por el administrador, como las Listas de Control de Acceso, definen los recursos a los que cada usuario puede acceder y los privilegios de que dispone. Todo el código que ejecute un usuario lo hará dentro de su contexto de seguridad, de manera que el código podrá acceder a todos los recursos a los que el usuario tiene acceso.
El mayor problema de los sistemas de seguridad basados en la identidad del usuario es la granularidad de usuario que introducen: cualquier código que se ejecute en nombre del usuario lo hará en su contexto de seguridad, con los mismos privilegios de acceso a los recursos protegidos. Es decir, no se hace ninguna distinción de confianza respecto al código mismo: puede ser una aplicación legítima o un virus. Esta limitación abre la puerta a todo tipo de ataques procedentes del código móvil malicioso. En cambio, tanto Java como la plataforma .Net incorporan un sistema de seguridad basado en la identidad del código.
Cuando se ejecuta una aplicación, el motor de tiempo de ejecución (Java Runtime Environment o JRE en Java y Common Language Runtime o CLR en .Net) la evalúa automáticamente y le concede un conjunto de permisos. En función de los permisos que reciba la aplicación, se ejecutará correctamente o se generará una excepción de seguridad. La configuración de seguridad local de un equipo concreto decide en última instancia los permisos que recibe el código. Dado que esta configuración puede variar de un equipo a otro, nunca se podrá saber con certeza si el código va a recibir los permisos suficientes para ejecutarse. En una organización, donde el parque informático está controlado, pueden configurarse todos los equipos con políticas definidas por los administradores. Sin embargo, en el caso de los usuarios domésticos y la mayoría de PYMES, lo más probable es que no exista ninguna directiva de seguridad activada.
Los sistemas de seguridad basados en la identidad de código autentican al propio código mediante la recopilación de información acerca del origen y del autor del mismo. De esta forma, la seguridad basada en la identidad de código sirve para complementar la seguridad basada en la identidad de usuario. El código ejecutado en nombre del usuario está sujeto a ulteriores limitaciones de confianza en función de su origen y autor. Los derechos de acceso del código que ejecute el usuario serán la intersección de sus derechos como usuario y de los derechos del código, de manera que siempre se aplicarán las medidas más restrictivas. Por lo tanto, cuando ambos modelos de seguridad conviven, las limitaciones impuestas al código dependerán tanto del usuario que lo ejecuta como del origen y autor del propio código. El resultado final es una drástica ganancia en seguridad.

Autenticación y autorización de código en .Net
En la plataforma .Net, la autenticación y autorización de código reciben el nombre genérico de Seguridad de Acceso a Código (Code Access Security o CAS). La evidencia constituye la pieza clave del modelo CAS de .Net, que se aplica al código que se está ejecutando y no al usuario que lo ejecuta. En .Net se entiende por evidencia el conjunto de información que el CLR utiliza para tomar decisiones basándose en la directiva de seguridad. La evidencia indica al motor de tiempo de ejecución que el código tiene una característica concreta. Entre los tipos de evidencia normales están las firmas digitales y la ubicación de origen del código, pero la evidencia puede tener también un diseño personalizado que represente otra información de importancia para la aplicación. Tanto los ensamblados como los dominios de aplicación reciben las concesiones de permisos según la evidencia. A la hora de evaluar las directivas de seguridad, se pueden proporcionar los tipos de evidencia siguientes:
ApplicationDirectory: El directorio de la aplicación que va a ejecutarse.
Hash: Cuando se compila un ensamblado puede calcularse su hash. Conocido el hash de un ensamblado debería ser imposible crear otro ensamblado con el mismo valor de hash. Se trata, por tanto, de una evidencia muy robusta. Puede utilizarse cuando se conozcan a priori los hashes de los ensamblados a ejecutar.
Publisher: Es la firma digital Authenticode X.509v3 de un ensamblado de código. Este tipo de firmas fueron tratadas en la anterior entrega. Proporcionan una evidencia muy robusta, que no requiere conocer con anterioridad a su ejecución el ensamblado que va a ejecutarse, sino solamente a su autor.
Site: El sitio web desde el que se descargó el ensamblado.
StrongName: El nombre seguro de un ensamblado. Aunque consiste en una firma digital, no es una evidencia tan robusta como la firma digital Authenticode (Publisher), ya que el nombre seguro no viene avalado por una autoridad de certificación.
Url: La dirección URL desde la que se descargó el ensamblado.
Zone: La zona de seguridad en relación a Internet Explorer de un ensamblado.
La evidencia se calcula y aplica dinámicamente para el código en ejecución, no es algo que esté precalculado o almacenado en caché. Algunas evidencias, como Hash, Publisher o StrongName, son internas, es decir, proporcionadas por el propio ensamblado; mientras que otras son de origen, como Url, Site, ApplicationDirectory o Zone, proporcionadas por el host donde se ejecuta el ensamblado. Como ejemplos de hosts pueden citarse ASP.Net, Internet Explorer o la línea de comandos.
Una vez acumuladas diversas evidencias acerca del código es posible autenticarlo. Pero la sola identifi

Contenidos recomendados...

Comentar
Para comentar, es necesario iniciar sesión
Se muestran 0 comentarios
X

Uso de cookies

Esta web utiliza cookies técnicas, de personalización y análisis, propias y de terceros, para facilitarle la navegación de forma anónima y analizar estadísticas del uso de la web. Consideramos que si continúa navegando, acepta su uso. Obtener más información