Compartir a través de


Seguridad en las bibliotecas de clases

Los diseñadores de bibliotecas de clases deben comprender la seguridad de acceso a código para escribir bibliotecas de clases seguras. Cuando se escribe una biblioteca de clases, hay que tener en cuenta dos principios de seguridad: proteger los objetos con permisos y escribir código de plena confianza. El grado en que se apliquen estos dos principios dependerá de la clase que se escriba. Algunas clases, como la Clase System.IO.FileStream, representan objetos que es necesario proteger con permisos. La implementación de estas clases es responsable de comprobar los permisos de llamadores y de permitir sólo a los llamadores autorizados realizar operaciones para las que tengan permisos. System.Security (Espacio de nombres) contiene clases que ayudan a realizar estas comprobaciones en las bibliotecas de clases que se escriban. El código de bibliotecas de clases a menudo es código de plena confianza o como mínimo de alta confianza. Dado que el código de bibliotecas de clases tiene acceso con bastante frecuencia a recursos protegidos y código no administrado, cualquier defecto del código representa una grave amenaza a la integridad de todo el sistema de seguridad. Para minimizar los peligros relacionados con la seguridad, siga las instrucciones que se describen en este tema cuando escriba código de bibliotecas de clases. Para obtener más información, vea Escribir bibliotecas de clases seguras.

Proteger objetos con permisos

Los permisos se definen para proteger recursos específicos. Una biblioteca de clases que realiza operaciones en recursos protegidos debe exigir esta protección Antes de realizar alguna acción en la solicitud de un recurso protegido, como eliminar un archivo, el código de la biblioteca de clases debe comprobar, en primer lugar, que el llamador tiene permiso (y, normalmente, todos los llamadores, mediante el recorrido de pila) para eliminar el recurso. Si el llamador tiene el permiso adecuado, permitirá completar la acción. Si el llamador no tiene permiso, la acción no debe completarse y se debe provocar una excepción de seguridad. La protección se implementa, por lo general, en el código con una comprobación declarativa o una comprobación imperativa de los permisos apropiados.

Es importante que las clases protejan los recursos, no sólo contra el acceso directo, sino también contra cualquier tipo de exposición posible. Por ejemplo, el objeto de un archivo almacenado en la caché es responsable de comprobar los permisos de lectura del archivo, aunque los datos reales se recuperen de una caché en memoria y no se produzca ninguna operación real en el archivo. Esto es así porque el efecto de pasar datos al llamador es el mismo que si el llamador realiza una operación de lectura real.

Código de biblioteca de clases de plena confianza

En la mayoría de las bibliotecas de clases se implementa código de plena confianza que encapsula la funcionalidad específica de la plataforma como objetos administrados, por ejemplo, las API del sistema o de COM. El código de plena confianza puede exponer una debilidad en la seguridad de todo el sistema. No obstante, esto no debe ocurrir si las bibliotecas de clases se escriben correctamente con relación a la seguridad, colocando una alta carga de seguridad en un conjunto de bibliotecas de clases relativamente pequeño; y permitiendo que la parte más extensa del código administrado adquiera la seguridad principal en tiempo de ejecución de estas bibliotecas de clases principales.

En un escenario habitual de seguridad de bibliotecas de clases, una clase de plena confianza expone un recurso protegido mediante un permiso; para tener acceso al recurso se utiliza una API de código nativo. Un ejemplo típico de este tipo de recurso es un archivo. La Clase File utiliza una API nativa para realizar operaciones en el archivo, como la eliminación. Para proteger el recurso, se realizan los pasos siguientes.

  1. Un llamador solicita la eliminación del archivo c:\test.txt llamando al Método File.Delete.
  2. El método Delete crea un objeto de permiso que representa el permiso delete c:\test.txt.
  3. El código de la clase File comprueba todos los llamadores de la pila para ver si tienen el permiso solicitado; si no se les ha concedido el permiso, se provoca una excepción de seguridad.
  4. La clase File declara FullTrust para llamar al código nativo, porque sus llamadores no tienen este permiso.
  5. La clase File utiliza una API nativa para realizar la operación de eliminación del archivo.
  6. La clase File devuelve a su llamador, y la solicitud de eliminación del archivo se completa correctamente.

Precauciones para código de alta confianza

El código de una biblioteca de clases de confianza concede permisos que no están disponibles en el código de la mayoría de las aplicaciones. Además, un ensamblado puede contener clases que no necesitan permisos especiales, pero que se conceden porque el ensamblado contiene otras clases que requieren estos permisos. Estas situaciones pueden exponer una debilidad en la seguridad del sistema. Por tanto, se debe tener un cuidado especial cuando se escribe código de plena confianza y código de alta confianza.

Diseñe código de confianza para que se pueda llamar mediante un código de confianza parcial del sistema sin exponer puntos vulnerables de seguridad. Generalmente, los recursos se protegen mediante el recorrido de la pila de todos los llamadores. Si un llamador no tiene suficientes permisos, se bloquea el intento de acceso. Sin embargo, siempre que el código de confianza declare un permiso, el código tiene la responsabilidad de comprobar los permisos requeridos. Normalmente, una aserción debe ir seguida de una comprobación de los permisos del llamador como se ha descrito anteriormente en este tema. Además, se debe minimizar el número de aserciones de permisos para reducir el riesgo de exposiciones inintencionadas.

Al código de plena confianza se concede implícitamente el resto de los permisos. Además, permite infringir las reglas de seguridad de tipos y de uso de objetos. Independientemente de la protección de recursos, cualquier aspecto de la interfaz de programación que pueda descifrar la seguridad de tipos o permitir el acceso de datos que, por lo general, no están disponibles para el llamador pueden provocar problemas en la seguridad.

Rendimiento

Las comprobaciones de seguridad incluyen la comprobación de los permisos de los llamadores en la pila. En función de la profundidad de la pila, estas operaciones pueden tener un costo muy elevado. Si una operación consiste en realidad en un número de acciones en un nivel inferior en el que es necesario realizar comprobaciones de seguridad, el rendimiento puede mejorar enormemente si se comprueban los permisos de los llamadores una vez y, a continuación, se declara el permiso necesario antes de realizar acciones. Esta aserción detendrá la propagación del recorrido por la pila en un punto para efectuar correctamente la comprobación. Normalmente, está técnica da como resultado una mejora del rendimiento si se realizan tres o más comprobaciones de permisos cada vez.

Resumen de los problemas de seguridad de las bibliotecas de clases

  • En las bibliotecas de clases que utilizan recursos protegidos se debe garantizar que sólo se utilizan estos recursos en los permisos de los llamadores.
  • La aserción de permisos se debe efectuar sólo cuando es necesario y debe ir precedida de las necesarias comprobaciones de permisos.
  • Para mejorar el rendimiento, agregue operaciones que incluyan comprobaciones de seguridad y considere la posibilidad de utilizar aserciones para limitar los recorridos de la pila sin poner en peligro la seguridad.
  • Tenga en cuenta que un llamador malicioso de confianza parcial puede en potencia utilizar una clase para omitir la seguridad.
  • No dé por supuesto que sólo los llamadores con permisos específicos llamarán al código.
  • No defina interfaces sin seguridad de tipos, pues pueden ser utilizadas para omitir la seguridad en otros lugares.
  • No exponga la funcionalidad en una clase que permita a un llamador de confianza parcial aprovecharse de la confianza superior de la clase.

Vea también

Instrucciones de diseño para programadores de bibliotecas de clases | Escribir bibliotecas de clases seguras | Seguridad de acceso a código | Operaciones de cadenas que tengan en cuenta las referencias culturales y la seguridad