2009-05-21 6 views
11

He visto que puede manipular private and internal members using reflection. También lo he visto decir que un 'sealed' class is more secure that one that isn't.¿Los niveles de acceso y modificadores (privados, sellados, etc.) cumplen una función de seguridad en C#?

¿Son los modificadores "públicos, protegidos, internos, privados, abstractos, sellados, de solo lectura" algo más que un acuerdo de caballeros sobre el diseño y el uso de API, que pueden romperse mientras tenga acceso a la reflexión? Y si un hacker ya está ejecutando código que llama a su API, el juego ya está perdido, ¿no?

¿Los siguientes son más seguros que cualquier otra clase?

//private class 
sealed class User 
{ 
    private string _secret = "shazam"; 
    public readonly decimal YourSalary; 
    public string YourOffice{get;}; 
    private DoPrivilegedAction() 
    { 
    } 
} 
+0

Un "hacker" podría modificar su código sin los metadatos de .Net y Java. Alguien recuerda DeHacked http://en.wikipedia.org/wiki/Dehacked Todo lo que puede hacer es esperar que sea lo más difícil posible. –

Respuesta

27

En primer lugar, para responder a su pregunta: El sistema de seguridad está diseñado para proteger BUENOS USUARIOS a partir del MALO CÓDIGO; explícitamente no está diseñado para proteger el BUEN CÓDIGO de los MALOS USUARIOS.Sus restricciones de acceso mitigan los ataques a sus usuarios por código hostil parcialmente confiable. No mitigan los ataques en su código de usuarios hostiles. Si la amenaza es que los usuarios hostiles obtengan su código, entonces usted tiene un gran problema. El sistema de seguridad no mitiga esa amenaza en absoluto.

En segundo lugar, para abordar algunas de las respuestas anteriores: comprender la relación completa entre la reflexión y la seguridad requiere una cuidadosa atención a los detalles y una buena comprensión de los detalles del sistema CAS. Las respuestas publicadas anteriormente que afirman que no existe conexión entre la seguridad y el acceso debido a la reflexión son engañosas y erróneas.

Sí, la reflexión le permite anular las restricciones de "visibilidad" (a veces). Eso no implica que no haya conexión entre el acceso y la seguridad. La conexión es que el derecho a utilizar la reflexión para anular las restricciones de acceso está profundamente conectado al sistema CAS de múltiples maneras.

En primer lugar, para hacerlo arbitrariamente, el sistema CAS debe otorgar permiso de reflexión privado. Por lo general, esto solo se concede al código completamente confiable, que, después de todo, ya podría hacer cualquier cosa.

En segundo lugar, en el nuevo modelo de seguridad .NET, suponga que al conjunto A se le otorga un superconjunto del conjunto de concesión del conjunto B por el sistema CAS. En este escenario, el código en el conjunto A puede usar la reflexión para observar las partes internas de B.

En tercer lugar, las cosas se complican bastante cuando se agrega código generado dinámicamente a la mezcla. Una explicación de cómo funciona "Omitir visibilidad" frente a "Visibilidad de omisión restringida", y cómo cambian las interacciones entre reflexión, control de acceso y el sistema de seguridad en escenarios donde se escupió código en tiempo de ejecución me llevaría más tiempo y espacio que tener disponible. Vea el blog de Shawn Farkas si necesita detalles.

+1

Si entiendo correctamente, entonces el código con restrictivo private/sealed/readonly realmente es más seguro si uno está ejecutando el código potencialmente hostil en, digamos, confianza media. – MatthewMartin

+1

Correcto. Por supuesto, si el código hostil es completamente confiable, entonces ya se acabó el juego, hombre. El código hostil de confianza completa puede hacer cualquier cosa mala que quiera. ¡Confianza total significa _full_ confianza! –

6

No. Estos no tienen nada que ver con la seguridad. La reflexión los quiebra a todos.

+1

Esto es engañoso. Ver mi respuesta para más detalles. –

+0

Eric, el OP estipuló, "siempre y cuando tenga acceso a Reflection". ¿Hay situaciones en las que el código pueda tener acceso a Reflection, pero se le impida el acceso a miembros y tipos internos, privados, internos, protegidos o protegidos? –

+0

Sí, pero es casi seguro que no se encontrará con ellos a menos que sea un compilador que escribe un compilador que funciona con Silverlight. Existen escenarios poco claros que incluyen Silverlight, código generado dinámicamente a partir de árboles de expresiones y clases de cierre generadas por el compilador. Terminamos haciendo pequeños cambios en el sistema de seguridad de Silverlight para solucionar los problemas, pero aún hay problemas potenciales que esperamos abordar en futuras versiones. –

11

Los modificadores de acceso no se tratan de seguridad, sino de un buen diseño. Los niveles de acceso adecuados para las clases y los métodos impulsan/imponen buenos principios de diseño. La reflexión debería, idealmente, usarse solo cuando la conveniencia de usarla proporciona más utilidad que el costo de violar (si existe) las mejores prácticas de diseño. Las clases de sellado solo sirven para evitar que los desarrolladores amplíen su clase y "rompan" su funcionalidad. Hay diferentes opiniones sobre la utilidad de las clases de sellado, pero como hago TDD y es difícil burlarme de una clase sellada, la evito tanto como sea posible.

Si desea seguridad, debe seguir las prácticas de codificación que evitan que los malos ingresen y/o protejan la información confidencial de la inspección, incluso si ocurre una interrupción. La prevención de intrusiones, la detección de intrusos, el cifrado, la auditoría, etc. son algunas de las herramientas que debe emplear para proteger su aplicación. La configuración de modificadores de acceso restrictivos y clases de sellado tiene poco que ver con la seguridad de la aplicación, IMO.

1

En cuanto a los comentarios sobre reflexión y seguridad, tenga en cuenta que hay muchos tipos internos + miembros en mscorlib.dll que llaman a las funciones nativas de Windows y pueden generar maldad si una aplicación malintencionada utiliza el reflejo para llamar a ellos. Esto no es necesariamente un problema ya que el tiempo de ejecución normalmente no otorga estos permisos a las aplicaciones que no son de confianza. Esto (y algunas comprobaciones de seguridad declarativas) es cómo el binario mscorlib.dll puede exponer sus tipos a todo tipo de código confiable y no confiable, sin embargo, el código que no es de confianza no puede sortear la API pública.

Esto realmente solo está arañando la superficie del problema de reflexión + seguridad, pero con suerte es suficiente información para guiarlo por el camino correcto.

1

Siempre trato de bloquear las cosas con el mínimo acceso requerido. Al igual que tvanfosson, se trata de diseño más que de seguridad.

Por ejemplo, haré una interfaz pública, y mis implementaciones serán internas, y luego una clase de fábrica pública/métodos para obtener las implementaciones. Esto prácticamente obliga a los consumidores a escribirlo siempre como interfaz, y no como implementación.

Dicho esto, un desarrollador podría usar el reflejo para crear una instancia nueva de un tipo de implementación. No hay nada que lo detenga. Sin embargo, puedo descansar sabiendo que hice que al menos sea algo difícil violar el diseño.

Cuestiones relacionadas