Exportar (0) Imprimir
Expandir todo
Expandir Minimizar

Directrices de patterns & practices: seguridad (creación de aplicaciones distribuidas)

18 de Julio de 2005

Publicado: Enero de 2005

Keith Pleas

Microsoft Corporation

Este artículo se aplica a:

Seguridad de patterns & practices

Microsoft .NET Framework

Resumen: cree aplicaciones seguras en la plataforma Microsoft con las guías de patterns & practices descritas en este artículo. (14 páginas impresas.)

En esta página

Introducción Introducción
Guías de seguridad de patterns & practices Guías de seguridad de patterns & practices
Aplicaciones de ejemplo Aplicaciones de ejemplo
El "mundo real" El "mundo real"
Alojamiento comercial Alojamiento comercial
Conclusión Conclusión

Introducción

¿Qué tienen en común libros, equipos para espías, almacenes, bicicletas y productos para animales domésticos? Microsoft los ha utilizado todos como base para aplicaciones de ejemplo basadas en Web de empresa a consumidor. Aunque dos de estas aplicaciones de ejemplo (Duwamish Books y Fitch & Mather Stocks (F&M)) tienen su origen en la clásica era COM y, tras cierto número de actualizaciones, se incluyen ahora con las versiones Enterprise de Microsoft Visual Studio .NET, hay un número sorprendentemente grande de aplicaciones reales que se han creado a partir de los ejemplos de comercio electrónico de IBuySpy y su portal relacionado. Y mientras que PetShop 3.0 (en inglés) pretende mostrar "una arquitectura empresarial para crear aplicaciones Web .NET" que "cumpla las guías de arquitectura prescriptiva de Microsoft", es poco probable que haya muchas aplicaciones de producción que se hayan creado a partir de ella: el motivo de su existencia es que es una versión .NET de la aplicación Pet Store de Sun Microsystems.

Mientras que la mayoría de las aplicaciones de comercio electrónico comparten varias características de diseño (por ejemplo, exploración de catálogos, inicio de sesión validado y carros de la compra), lo que tiende a ser un factor diferenciador (aparte de los productos vendidos) es el tratamiento de los datos específicos de los clientes. Y los datos de los clientes están íntimamente ligados a la seguridad. Muchos desarrolladores suponen que estas aplicaciones de ejemplo, diseñadas para servir como plantillas a partir de las que los desarrolladores pueden escribir aplicaciones para el mundo real, deben seguir las "prácticas más adecuadas" en temas importantes no relacionados con la funcionalidad como el rendimiento, la escalabilidad y la seguridad. Desgraciadamente, para que estos ejemplos se puedan instalar y examinar en las estaciones de trabajo de los desarrolladores, incorporan un cierto número de omisiones y simplificaciones, lo que es especialmente cierto en lo relativo a la seguridad. Aunque las medidas de seguridad adicionales se describen en la documentación que acompaña a estos ejemplos, es fácil que esta información fundamental se pase por alto.

Guías de seguridad de patterns & practices

Por tanto, los desarrolladores utilizan las aplicaciones de ejemplo de Microsoft (con frecuencia creadas por los proveedores) que son más demostraciones educativas que auténticas plantillas para aplicaciones empresariales destinadas al mundo real. Los creadores de estas aplicaciones no son los únicos culpables: hasta hace poco, había poca información detallada acerca de cuáles son las "prácticas más adecuadas" del ciclo de vida de las aplicaciones. Los desarrolladores (y los diseñadores) cada vez prestan más atención a los "patrones de diseño", que constituyen una parte importante de la información que ofrece patterns & practices de Microsoft, con patrones de diseño y prácticas operacionales. Estas directrices están disponibles de manera gratuita en formato electrónico (normalmente como documentos PDF) en el sitio Web patterns & practices (en inglés). También se pueden pedir versiones impresas en formato libro aquí (en inglés).

En lo que se refiere a la seguridad de las aplicaciones, hay dos publicaciones de patterns & practices de especial interés:

  • Crear aplicaciones ASP.NET seguras

  • Mejora de la seguridad de aplicaciones Web: amenazas y contramedidas

Aunque estas guías ofrecen una enorme cantidad de información útil, necesariamente reflejan algunas simplificaciones que tal vez no sean adecuadas para su caso concreto. Una de estas simplificaciones supone que las personas que implementan y administran la aplicación tienen control de administrador sobre los equipos de la infraestructura de destino, lo cual no es cierto casi nunca. En concreto, normalmente las aplicaciones alojadas se encuentran en equipos con niveles de seguridad considerablemente mayores (y, por tanto, con privilegios reducidos) disponibles para los "propietarios" de las aplicaciones.

Creación de aplicaciones Web seguras

La primera guía de seguridad que proporcionó la iniciativa patterns & practices fue Crear aplicaciones ASP .NET seguras. Esta guía se escribió poco antes del lanzamiento de la versión 1.1 de Microsoft .NET Framework y Microsoft Windows Server 2003, cuando aún estaban en versión beta, y prácticamente no describe ningún "patrón de diseño" relativo a la seguridad. Más bien, describe dos enfoques diferentes de la seguridad del acceso a los recursos:

  • El modelo de subsistema de confianza

  • El modelo de suplantación y delegación

En general, las directrices de patterns & practices recomiendan el modelo de "subsistema de confianza". El modelo de "suplantación y delegación" (que suplanta a los autores originales de la llamada y delega en su nombre) implica claramente que también se está administrando información de cuenta relativa a los usuarios en el sistema de seguridad de la base de datos (por lo que probablemente se utilice la autenticación SQL para SQL Server). En un modelo de "subsistema de confianza", se le asigna al autor original de la llamada una función y, a continuación, se le autoriza el acceso al recurso (incluida la base de datos) de acuerdo con la pertenencia a funciones. Este modelo permite utilizar cuentas de servicio, incluida la cuenta Microsoft ASP.NET en el caso de una aplicación Web, lo que implica también la autenticación de Windows en la base de datos.

El modelo de subsistema de confianza admite la agrupación de conexiones, un requisito clave para lograr una aplicación de alta escalabilidad. Además, los usuarios no pueden tener acceso directamente a los datos y el mantenimiento de la información de seguridad en la base de datos se reduce al mínimo.

En cada uno de estos dos enfoques, hay un método recomendado para autorizar el acceso a los recursos. El "patrón" general descrito para el modelo de subsistema de confianza puede resumirse de la siguiente manera:

  1. Autenticar a los usuarios

  2. Asignar funciones a los usuarios

  3. Autorizar dependiendo de la pertenencia a funciones

  4. Realizar el acceso al administrador de recursos descendentes con una identidad de confianza fija

El "patrón" equivalente para el modelo de suplantación y delegación no se detalla explícitamente, pero equivaldría a lo siguiente:

  1. Autenticar a los usuarios

  2. Realizar el acceso a los recursos descendentes utilizando la identidad del cliente, mediante la suplantación para los recursos locales (en el mismo equipo) y la delegación para los recursos ubicados en equipos remotos

Ambos modelos de acceso a los recursos tienen ventajas e inconvenientes, pero tal vez no sea tarea del diseñador o desarrollador de la aplicación elegir qué modelo utilizar. Más bien, serán requisitos no relacionados con la funcionalidad los que determinen el enfoque necesario. Por ejemplo, los requisitos de auditoría pueden obligar a guardar registros detallados del acceso a los recursos que muestren los usuarios concretos, cuyos detalles se enmascaran en el modelo del subsistema de confianza. De manera similar, se puede implementar la aplicación en un entorno alojado en el que no haya acceso a características del sistema como cuentas de servicio y, en el caso de SQL Server, no se permita la seguridad integrada de Windows. Por otra parte, si el rendimiento es un factor importante, resulta preferible el modelo de subsistema de confianza ya que ofrece un mayor rendimiento y escalabilidad, mediante la implementación de características como el almacenamiento en caché y la agrupación de conexiones, que sólo tienen sentido en la identidad "agregada" del subsistema de confianza.

Para complicarlo todo aún más, la propia infraestructura de TI existente puede afectar al enfoque preferido. Por ejemplo, la suplantación no se recomienda en Windows 2000 ya que a la cuenta ASP.NET hay que concederle el privilegio "Actuar como parte del sistema operativo", lo que se considera como intrínsecamente inseguro. Este requisito se relajó en Windows Server 2003 (junto con el cambio del modelo del proceso) y las aplicaciones implementadas en esta versión del sistema operativo de servidor y en versiones posteriores pueden utilizar ambos enfoques sin quedar expuestas a este problema de seguridad concreto. Además, IIS 6.0 (parte de Windows Server 2003) proporciona un mayor aislamiento de los procesos, además de utilizar la cuenta de usuario de servicio de red, más segura, en lugar de la cuenta ASP.NET utilizada anteriormente.

Independientemente del enfoque elegido, ambos comienzan por la autenticación de los usuarios. Y aquí también hay varias opciones: ASP.NET admite cuatro modos de autenticación (ninguna, formularios, Windows y Passport), mientras que la autenticación de Windows ASP.NET ofrece cinco modos correspondientes para autenticación IIS (anónima, básica, implícita, integrada de Windows y personalizada). La autenticación IIS personalizada también se puede utilizar cuando la autenticación ASP.NET se establece en "ninguna". Evidentemente, el "mejor" enfoque depende de la infraestructura y de los requisitos de la aplicación. Eso es sólo para la autenticación: la autorización del acceso a los recursos puede implicar una complejidad adicional. Un "patrón" de autorización general incluye los siguientes pasos:

  1. Recuperar las credenciales

  2. Validar las credenciales

  3. Colocar a los usuarios en funciones

  4. Crear un objeto IPrincipal

  5. Colocar el objeto IPrincipal en el contexto HTTP actual

  6. Autorizar en función de la identidad del usuario y la pertenencia a funciones

Si se elige la autenticación Windows, ASP.NET administrará automáticamente todos los pasos salvo el último.

Cada uno de estos métodos de autorización y autenticación se describen en Crear aplicaciones ASP .NET seguras, que también incluye varios procedimientos prácticos al final del documento, como "Cómo: Utilizar la autenticación mediante formularios con SQL Server 2000" y "Cómo: Crear una biblioteca de cifrado".

Mejora de la seguridad de las aplicaciones Web

El segundo volumen de las directrices de seguridad de patterns & practices integra la infraestructura (o ITPRO, según la terminología de Microsoft) con el desarrollador. O, dicho de otro modo, integra los mundos de los usuarios cuya historia de soporte de Microsoft empieza con TechNet con los que empiezan con MSDN. Es una idea realmente buena, ya que los desarrolladores deben aprender más acerca de cómo las aplicaciones se implementan realmente para poder crearlas y probarlas en este tipo de entorno. Lo ideal sería que los desarrolladores tuvieran un sistema de desarrollo completo con el que trabajar, pero tal vez deberíamos reservar este tema para otro momento.

La mayoría de los sistemas protegen los datos de la base de datos y (con cierta menor frecuencia) cuando se transfieren a través de la red protegiendo el canal (normalmente mediante SSL) o cifrando los datos. Lo que suele pasarse por alto, sin embargo, es la protección de los datos dentro de la aplicación ejecutable. En una aplicación Web, los datos confidenciales (así como el estado de vista del control y la página correspondientes, si se han implementado) suelen vincularse a un cliente como parte del estado de la sesión. Cada sesión de ASP.NET se asocia a una cadena de 120 bits SessionID generada aleatoriamente y la protección de dicha cadena es fundamental para proteger la aplicación de una intrusión no autorizada. SessionID suele pasarse mediante una cookie HTTP o una dirección URL modificada, por lo que puede imaginarse lo fácil que resulta interceptar este valor si se transmite a través de una conexión de red no cifrada.

Mejora de la seguridad de aplicaciones Web presenta el nuevo término "token de la sesión" para referirse a SessionID. Aunque este nuevo uso de la palabra "token" resulta bastante novedoso, al menos el significado está muy claro. Este mismo documento utiliza también "token de autenticación" para referirse a la cookie de autenticación de formularios. Es importante no confundir estos "tokens" con los que .NET Framework SDK y Platform SDK (que pronto se combinarán juntos) denominan un "token de acceso". Técnicamente, un token de acceso es un "token primario" o un "token de suplantación" y contiene la información de seguridad correspondiente a una sesión de inicio de sesión. Identifica al usuario, sus grupos y sus privilegios.

Aparte de la creatividad de su terminología, Mejora de la seguridad de aplicaciones Web proporciona ciertos consejos sólidos de seguridad. Para la administración de sesiones mediante autenticación por formularios, recomienda (combinación de las listas de Parte 2: Diseño de aplicaciones Web seguras y Parte 3: Creación de aplicaciones Web seguras):

  1. Proteger las páginas confidenciales mediante SSL y requerir autenticación

  2. Proteger el estado de la sesión respecto al acceso no autorizado

  3. No confiar en las opciones de administración del estado en el cliente

  4. No mezclar tokens de sesión y tokens de autenticación

  5. Utilizar SSL para proteger las cookies de autenticación de la sesión

  6. Cifrar el contenido de las cookies de autenticación

  7. Limitar la duración de la sesión

La quinta recomendación en realidad debería haber sido "Utilizar SSL para proteger la sesión y las cookies de autenticación" para ser coherente con la práctica de separar la sesión de la parte segura (autenticada) de la aplicación. ¿Por qué es necesario establecer esta separación? En primer lugar, es necesario asegurarse de que no basta con un SessionID para tener acceso a las páginas seguras. Las páginas seguras deben requerir el token de autenticación de formularios, que sólo se pasa a través de una conexión segura cuando se establece requireSSL="true" en el elemento <forms>. En segundo lugar, esto permite separar la administración de la cookie de autenticación de formularios, que puede contener datos confidenciales del usuario en forma de varios pares de clave y valor. Se puede configurar la seguridad, persistencia, caducidad y dominio o ruta de acceso de la cookie de autenticación de formularios.

Claramente, todas estas recomendaciones son prácticas válidas que aumentan la seguridad de la sesión. Sin embargo, también dependen de lo que ofrezca o permita la infraestructura. También hay varios niveles de "costo" asociados con estas recomendaciones en términos de desarrollo, comprobación y administración. Aunque exigir SSL es una opción de configuración sencilla, los certificados SSL propiamente dichos no son gratuitos a menos que esté utilizando su propia entidad emisora de certificados de raíz (CA raíz). Si lo hace, no obstante, los usuarios no reconocerían la CA raíz, a menos que el administrador haya rellenado previamente sus listas de entidades de certificación utilizando el Internet Explorer Administration Kit (IEAK) o que acepten manualmente el certificado raíz.

La duración de la sesión se puede configurar en el elemento <sessionState> de machine.config y en el Web.config de la aplicación. El valor predeterminado es de 20 minutos. También debe limitar la duración de las cookies. El tiempo de espera predeterminado de las cookies (que se configura en el elemento <forms>) es de 30 minutos y las directrices de patterns & practices sugieren que este valor se reduzca a 10 minutos, lo que limitará la ventana de oportunidad para los ataques de repetición de cookies.

En el servidor, las aplicaciones deben ser conscientes de estar utilizando datos confidenciales del usuario. En general, estos datos deben recuperarse únicamente cuando sea necesario y descartarse tan pronto como se utilicen.

En vez de almacenar datos confidenciales, una práctica habitual consiste en almacenar versiones de los datos a las que se aplica un hash y un valor de salt, que se pueden utilizar para la validación. Además, si los datos confidenciales se envían a través de un canal de comunicaciones, se deberá proteger dicho canal o cifrar los propios datos. Este requisito suele aplicarse a los datos intercambiados con servicios Web.

En un entorno de conjunto de servidores Web, el estado de la sesión de la aplicación normalmente se mantiene en todos los servidores en un almacén duradero como una base de datos, mediante un servicio personalizado o utilizando el servidor de estado de ASP.NET. Si no lo comparten todos los servidores, entonces será necesario (mediante hardware o software) devolver las devoluciones posteriores de la sesión al mismo equipo de servidor físico. En la práctica, por desgracia, esta afinidad de la sesión puede afectar drásticamente el rendimiento.

Aplicaciones de ejemplo

Ahora que conocemos algunas de las directrices de seguridad recomendadas por Microsoft, podemos preguntarnos: ¿están a la altura de las circunstancias las aplicaciones de ejemplo? Veamos una "revisión de seguridad" de Duwamish y F&M para comprobarlo por nosotros mismos.

En primer lugar, tanto Duwamish como F&M utilizan la autenticación mediante formularios. Este enfoque no es necesariamente malo, ya que funciona con todos los tipos habituales de exploradores y no requiere que el sistema operativo de servidor sea Windows 2000 o 2003. Además, resulta práctico que los desarrolladores puedan examinar una aplicación de ejemplo (o los revisores de prensa o analistas, según corresponda). Por supuesto, esto también implica que la aplicación no puede mostrar ninguna técnica de seguridad específica de los servidores. En concreto, ninguna de las aplicaciones utiliza la seguridad basada en funciones ni el enfoque de subsistema de confianza, aunque la documentación incluida dedica una sección a la implementación de la seguridad basada en funciones.

Sin embargo, aunque estas dos aplicaciones de ejemplo utilizan la autenticación mediante formularios, siguen mostrando unas directrices de seguridad comunes. Por ejemplo, cualquier aplicación del "mundo real" normalmente cifraría las cookies de autenticación y utilizaría SSL para todas las páginas confidenciales. Estas páginas confidenciales suelen colocarse en un subdirectorio seguro que utiliza SSL, lo que reduce al mínimo el impacto sobre el rendimiento debido al uso de SSL.

Desgraciadamente, Duwamish y F&M no adoptaban (según sus propias palabras) un enfoque del "mundo real" para la seguridad. Y ahí está el problema. Fueron diseñados para desarrolladores y no se consideró práctico crear la arquitectura del "mundo real". Una vez dicho esto, hay una diferencia substancial entre los ejemplos que se proporcionan y cómo se suele suponer que deben ser las aplicaciones del "mundo real".

Por ejemplo, ninguno de los ejemplos refleja las directrices acerca del cifrado de las cookies de autenticación que se ha descrito anteriormente. Mejora de la seguridad de aplicaciones Web también recomienda que las aplicaciones especifiquen nombres únicos y atributos de ruta de acceso en el elemento <forms>, algo que no implementa ninguno de los ejemplos. Y en lo relativo a la SSL, la documentación de ambos ejemplos menciona el uso de SSL para el cifrado, pero esto solamente es posible en Duwamish, que coloca las páginas "confidenciales" en una raíz virtual "\secure" e incluye una opción de configuración para la habilitación de SSL, que redirige las solicitudes de pago "seguras" a otra raíz virtual habilitada con SSL. F&M simplifica aún más la protección de las comunicaciones e incluye un comentario "BehindTheScenes" que dice:

"Security Note - A deployed Internet application would post back login 
credentials using SSL to an HTTPS URL. Fitch and Mather 7.0 passes clear 
text passwords that anyone could obtain. Prior to deployment, it would be 
essential to address this serious security flaw"

Teniendo en cuenta que tanto Duwamish como F&M utilizan SQL Server para sus bases de datos, sería deseable que ilustraran buenos principios de seguridad relativos al acceso a los datos. Bueno, la cuenta de usuario de SQL Server para Duwamish se denomina "Duwamish7vb_login" (para la versión de Visual Basic) y tiene la contraseña "password_03F47A8338304FD68A5B", que ciertamente es más segura que la cadena de conexión utilizada para el estado de la sesión:

sqlConnectionString="data source=127.0.0.1;user id=sa;password="

Irónicamente, esta conexión no se utiliza ya que el modo sessionState está establecido en "InProc" de manera predeterminada, pero la documentación detalla explícitamente cómo cambiarla para la implementación distribuida. Además, ciertamente por comodidad, pero desaconsejado, no obstante, todas las contraseñas se almacenan en texto sin cifrar en el archivo Web.Config.

Algunas de las directrices de seguridad de patterns & practices no parecen apropiadas para aplicaciones de ejemplo. Por ejemplo, Mejora de la seguridad de aplicaciones Web aconseja utilizar direcciones URL absolutas para redireccionar la exploración. Afortunadamente, es posible hacerlo no codificando estáticamente toda la dirección URL, sino construyendo una dirección URL:

// Form an absolute path using the server name and v-dir name
string serverName = HttpUtility.UrlEncode(Request.ServerVariables["SERVER_NAME"]);
string vdirName = Request.ApplicationPath;
Response.Redirect("https://" + serverName + vdirName + "/Restricted/Login.aspx");

Duwamish usa código equivalente, apropiadamente ubicado en la clase PageBase. Esta clase base permite que todas las páginas de la aplicación compartan una lógica de procesamiento común. El patrón de diseño general para esta clase base es el "controlador de páginas", que es una versión refinada del patrón de diseño "controlador-vista-modelo" que subyace bajo el modelo de procesamiento de páginas de ASP.NET. Puede encontrar más información acerca de estos patrones de diseño en el documento Enterprise Solution Patterns Using Microsoft .NET de patterns & practices. En todo caso, todas las páginas de Duwamish utilizan las siguientes propiedades:

Private ReadOnly Shared Property UrlSuffix As String
   Get
      UrlSuffix = HttpContext.Current.Request.Url.Host +
         HttpContext.Current.Request.ApplicationPath
   End Get
End Property

Public ReadOnly Shared Property UrlBase As String 
   Get
      UrlBase = "http://" & UrlSuffix 
   End Get
End Property

La restricción del acceso en Duwamish y F&M es igualmente desigual, siendo preferible Duwamish. Además de los problemas de SSL ya mencionados, las directrices de patterns & practices indican que las aplicaciones deben utilizar elementos <authorization> para restringir el acceso y obligar a iniciar sesión. En el directorio de aplicación de base, Duwamish utiliza la siguiente configuración de seguridad (en su mayor parte aceptable):

<authentication mode="Forms">
   <forms name=".ADUAUTH" loginUrl="secure\logon.aspx" protection="All">
   </forms>
</authentication>
<authorization>
   <allow users="*" />
</authorization>

La configuración protection="All" impone tanto la privacidad (cifrado) como la integridad (validación de datos) de la cookie de autenticación de formularios. Se establece el name, pero no hay ningún path que cree un hueco de seguridad con otra aplicación en un servidor alojado. Además, no se establece el timeout (y si hay una slidingExpiration que se restablece con cada solicitud), lo que implica que la cookie durará 30 minutos. Este timeout probablemente se debería reducir y también se debería tener en cuenta que el valor predeterminado de slidingExpiration cambió de true en la versión 1.0 de ASP.NET a false en la versión 1.1.

En la raíz virtual "secure", Duwamish utiliza esta configuración de seguridad:

<authorization>
   <deny users="?" />
   <allow users="*" />
</authorization>

Por tanto, el directorio Web "secure" primero rechaza a los usuarios anónimos, lo que también es una práctica adecuada.

Ahora examinemos F&M. A continuación, se indica la configuración de seguridad de raíz:

<authentication mode="Forms">
   <forms name="FMStocks7Auth" loginUrl="Login.aspx">
   </forms>
</authentication>

No hay ninguna protection (que, afortunadamente, toma el valor predeterminado All), ningún path y ningún timeout (que no sea el predeterminado). Desgraciadamente, F&M no tiene una raíz virtual "secure" y por tanto rechaza a los usuarios anónimos según la página (como se muestra en el siguiente ejemplo), lo cual es mucho más probable que cause errores de configuración:

<!-- Mark the AccountSummary.aspx page as available only to authorized users -->
  <location path="AccountSummary.aspx">
    <system.web>
      <authorization>
        <deny users="?" />
      </authorization>
    </system.web>
  </location>

Si todo esto no parece muy seguro, examinemos la configuración de seguridad de PetShop:

<authentication mode="Forms">
   <forms name="PetShopAuth" loginUrl="SignIn.aspx" protection="None" timeout="60" />
</authentication>

Veamos la configuración protection="None". All es el valor predeterminado (y recomendado), que combina el cifrado (por privacidad) y la validación (por integridad). Por tanto, esta aplicación queda abierta a la modificación de las cookies y los ataques de repetición. La implementación de SSL al menos eliminaría la captura de cookies mediante la supervisión de la red. PetShop también rechaza a los usuarios anónimos según la página, lo cual (una vez más) es mucho más probable que cause errores de configuración.

El "mundo real"

Tal como se señaló en toda la explicación acerca de las "prácticas más adecuadas" de seguridad, la infraestructura en la que se implementa la aplicación puede afectar considerablemente a las decisiones de diseño durante el desarrollo suponiendo, evidentemente, que el personal de desarrollo sepa cómo se configurará la infraestructura.

Por tanto, ¿cuáles son algunas de estas limitaciones del "mundo real"? Bien, para un proyecto reciente de un cliente de una importante corporación, el departamento de TI no estaba dispuesto a instalar ninguna versión beta de ningún sistema operativo, marco de trabajo de aplicación (es decir, en este caso, .NET Runtime) ni aplicaciones de soporte como SQL Server. Todos los equipos del centro de datos (en Web, aplicación y los niveles de datos) no estaban configurados para formar parte de un dominio y, por tanto, no había ningún Active Directory disponible. No se permitía el acceso directo a los archivos, ni tampoco ningún acceso de red fuera del equipo. No podíamos escribir en el Registro del sistema, solicitar ningún otro producto de software ni utilizar componentes basados en COM. Por tanto, evidentemente no podíamos utilizar componentes de servicio. Tampoco podíamos utilizar DPAPI (una biblioteca de seguridad basada en COM que se lanzó por primera vez con Microsoft Windows XP y recientemente con Windows Server 2003) para almacenar los nombres de los usuarios y las contraseñas en el Registro de manera cifrada. Cada aplicación podía tener su propia base de datos, por lo que la única opción de seguridad de SQL Server era la autenticación mediante SQL. También utilizaban de manera estándar Windows Server 2003 (con IIS 6.0) debido al mejor aislamiento de las aplicaciones.

Por supuesto, no era posible conectarse realmente con los equipos (ni utilizar FTP ni montar una unidad). En su lugar, los archivos se colocaban mediante una herramienta de publicación personalizada. Y si el archivo era una DLL, entonces tampoco se propagaba. Tras cierta negociación, conseguimos activar el servidor de estado en el "clúster" de Web, de otra manera hubiera tenido que ser el SQL Server compartido (tampoco se permitían soluciones de "afinidad").

Alojamiento comercial

Los host ASP.NET comerciales pueden ser realmente una alternativa más flexible a los departamentos de TI internos. No obstante, también son extremadamente sensibles a la seguridad, por lo que la mayoría de sus requisitos son paralelos a los de la restrictiva infraestructura corporativa, antes mencionada.

En la gama baja del mundo del alojamiento reina el caos. No se permiten inicios de sesión, ya que requerirían una cuenta de dominio, lo que resulta completamente imposible. No hay COM, no hay componentes facilitados como servicio, no hay protocolos y puertos de red que no sean el HTTP a través del puerto 80, FTP a través del puerto 21 y (con suerte) SSL a través del puerto 143. SSL requiere un certificado para la autenticación de servicios de fondo y los certificados del servidor no son gratuitos. Tal vez tenga acceso a un servicio SMTP, que requiera autenticación y no se haya convertido en un relé abierto. Acepte las condiciones, pague el dinero y ya puede marcharse.

Por tanto, ¿cómo afecta esto al diseño de aplicaciones? Para empezar, el único modelo posible es el de la suplantación y delegación: no queda otra posibilidad.

impersonate=true, lo que obliga a ejecutarlo como usuario anónimo. Afortunadamente, está aislado de los usuarios anónimos en otras cuentas. Probablemente también acabe con un gran número de identidades fijas en Web.config, por ejemplo:

<identity impersonate="true" userName="bob" password="inClearText"/>

Mientras que normalmente el archivo Web.config se protege mediante una lista de control de acceso (ACL) para limitar la visibilidad y las modificaciones, no suele ser posible con los hosts de las aplicaciones ya que implica configurar la seguridad de dominio (incluido el dominio local).

Es mejor que la base de datos sea segura, ya que no hay ninguna manera eficaz de evitar los ataques mediante inyección de SQL en un entorno alojado. Además, al no ser el administrador de la base de datos, necesitará cifrar todos los datos confidenciales de ésta. El servidor probablemente tendrá las extensiones de FrontPage (las requiere el programa de alojamiento comercial de Microsoft), pero tenga en cuenta que las extensiones de FrontPage no funcionan con la herramienta IISLockDown. Afortunadamente es así, ya que ejecutar la herramienta IISLockDown es probablemente el paso más importante que hay que llevar a cabo para proteger un servidor Web Windows 2000 o Windows 2003.

Seguridad de acceso al código (CAS)

Hasta ahora nos hemos centrado en la identidad, la autenticación y la autorización del usuario (o cuenta de servicio en el caso de un modelo de subsistema de confianza). Sin embargo, .NET Framework también ofrece varias maneras de identificar y proteger el código mediante un sistema denominado seguridad de acceso al código (CAS). En resumen, CAS permite darle una identidad al código (impuesta mediante un nombre seguro y un par de claves criptográficas) y restringir lo que el código puede hacer mediante un conjunto configurable de permisos de seguridad denominado directiva de seguridad.

Aunque CAS formaba parte de .NET Framework desde el principio, el código de confianza parcial (que permite la configuración de los niveles de confianza) sólo se habilitó a partir de la versión 1.1 de ASP.NET. El código de confianza parcial permite el llamado "modelo de restricción de recursos" que se puede configurar para restringir el acceso a determinados recursos, como el sistema de archivos, el Registro del sistema y los servicios de directorio. Como ASP.NET 1.0 no admitía el código de confianza parcial, todas las aplicaciones de ASP.NET 1.0 se ejecutan con plena confianza.

Aunque la configuración, comprobación y administración de código de confianza parcial es hoy día un proceso complejo y difícil, identificar el código (y restringir el código que puede llamarle) es un proceso mucho más sencillo. Tal vez la manera más fácil de ver lo útil que resulta consiste en imaginar un programa de contabilidad (o incluso un programa de talonario personal de cheques) que se ha dividido en varios componentes (denominados ensamblados en .NET). Si imponemos la identidad del código, un componente de la utilidad (que puede tener propiedades que devuelvan información confidencial como números de cuenta o métodos que realicen tareas esenciales como transferir dinero) sólo se podrá llamar desde un ensamblado firmado con un determinado nombre seguro, lo que evita que el ensamblado de la utilidad pueda ser "secuestrado" por otro código y obligado a realizar acciones indebidas. No olvide, sin embargo, que las peticiones de vínculos sólo comprueban al autor inmediato de la llamada.

La imposición de la identidad del autor de la llamada es la ventaja más inmediata del CAS. Es relativamente fácil de implementar por un desarrollador, ya que sólo requiere que el autor de la llamada tenga un nombre seguro y una petición de vínculo para la correspondiente clave de seguridad en el código al que se llama. La identidad del autor de la llamada también es fácil de comprobar. Basta con llamar al componente desde código sin firmar y comprobar si aparece una excepción de seguridad. Y lo mejor de todo es que no hay ningún requisito operativo adicional. Por supuesto, este método sólo funciona con componentes precompilados (incluidos los generados mediante el modelo de compilación de código subyacente de Visual Studio .NET). Incluso si hay que trabajar con código generado dinámicamente, el archivo de par de claves debería encontrarse en un directorio de la aplicación, lo que sería una práctica realmente desaconsejable desde el punto de vista de la seguridad. Aunque las documentaciones de Duwamish y F&M describen el proceso general para imponer la identidad del autor de la llamada mediante una petición de vínculo CAS, también debería haberse implementado en los ejemplos.

Las directrices de patterns & practices sobre la seguridad de acceso del código indican cómo hacerlo (a un nivel bastante alto), pero no explica cuándo hay que implementar CAS. Concretamente, Mejora de la seguridad de aplicaciones Web indica que los desarrolladores pueden utilizar CAS para restringir aún más el código al que puede llamar el código. Hay dos capítulos distintos de este volumen que explican a los desarrolladores cómo implementar (y a los administradores cómo configurar) CAS. Una implicación no especificada pero fundamental es que implica un alto nivel de coordinación entre el desarrollador y las operaciones, algo que no es posible en muchos entornos.

Mejora de la seguridad de aplicaciones Web también indica que el código de acceso a los recursos debe ubicarse en ensamblados distintos, lo que permite aplicar una directiva de forma más detallada. A continuación, el documento señala alegremente que "para ello es necesario cierta labor de reingeniería". Irónicamente, puede obligar a que la aplicación registre errores (mediante el registro de sucesos o una base de datos) pero es posible que el personal de operaciones no conceda permiso a la aplicación para que haga esto.

Debe investigar CAS si la infraestructura lo permite, pero siempre deberá implementarlo utilizando ensamblados con nombres seguros y peticiones de vínculos. Una ventaja concreta de utilizar peticiones de vínculos es que no es posible saltárselas (de manera accidental o adrede) cambiando trustLevel o configurando PermissionSet en Full.

Conclusión

Un sabio dijo una vez que "la seguridad debería ser barata para los amigos y cara para los enemigos". Cuando este concepto se aplica a algo tan sencillo como elegir contraseñas, quiere decir que los usuarios no deben tener que utilizar contraseñas imposibles de recordar porque no utilizarán la aplicación (por supuesto, para muchas personas esto no es una opción), o bien escribirán la contraseña y la colocarán en un lugar cómodo (como una nota pegada al monitor).

Debe ser fácil "hacer lo correcto" al desarrollar software seguro. Desgraciadamente, es un proceso complejo y difícil. Las dos guías de patterns & practices sobre la seguridad de aplicaciones Web tan sólo cubren algunas facetas de la seguridad y suponen un total de 1400 páginas. El libro Writing Secure Code de Microsoft Press, promocionado como "Una lectura obligada en Microsoft" y distribuido a todos los asistentes a la reciente Microsoft Professional Developers Conference (PDC), tiene 800 páginas y dedica un único capítulo específicamente a la escritura de código .NET. Hay pocas herramientas disponibles que ayuden a la realización de pruebas acerca de problemas de seguridad. Por tanto, apenas sorprende que los desarrolladores hayan tomado lo que básicamente son demostraciones de marketing para utilizarlas como plantillas a la hora de desarrollar sus propias aplicaciones. Desgraciadamente, las simplificaciones de estas demostraciones, aunque se destacan en la documentación, muchas veces no llegan a tenerse en cuenta.

Un aforismo familiar afirma que "si sólo tienes un martillo, todo te parece un clavo". ¿Por qué sorprenderse entonces de que muchas aplicaciones Web de producción sean muy similares a los ejemplos de demostración? Claramente, es necesaria una nueva generación de aplicaciones de ejemplo del mundo real que se hayan diseñado y creado utilizando las "prácticas más adecuadas" no sólo respecto a la seguridad (como hemos visto en este artículo), sino también respecto a la solidez, escalabilidad, comprobación e implementación; de hecho, todas las fases del ciclo vital de desarrollo de aplicaciones. También es importante reconocer que estas directrices mejorarán con el tiempo hasta que finalmente formen parte de la plataforma subyacente.

La primera aplicación de ejemplo de este tipo es una solución de referencia que implementa una arquitectura orientada a servicio (SOA) e incluye entradas de una gran comunidad interesada mediante GotDotNet workspace (en inglés). Finalmente, más aplicaciones del "mundo real", que tratan otros escenarios y reflejan el pensamiento actual, estarán disponibles para reemplazar a las aplicaciones de demostración simplificadas con las que se han familiarizado los desarrolladores. Asegúrese de consultar de vez en cuando la página principal de Microsoft patterns & practices (en inglés), ya que es seguro que aparecerán nuevas aplicaciones.

Mostrar:
© 2014 Microsoft