2009-05-21 2 views
11

Ich habe gesehen, dass Sie private and internal members using reflection manipulieren können. Ich habe auch gesehen, dass ein 'sealed' class is more secure that one that isn't.Erfüllen die Zugriffsebenen und Modifizierer (privat, versiegelt usw.) einen Sicherheitszweck in C#?

Sind die Modifikatoren "public, protected, internal, private, abstract, sealed, readonly" etwas mehr als ein Gentlemen's Agreement über Design und API-Verwendung, die gebrochen werden kann, solange Sie Zugang zu Reflektion haben? Und wenn ein Hacker bereits Code ausführt, der Ihre API aufruft, ist das Spiel bereits verloren, richtig?

Ist das Folgende sicherer als jede andere Klasse?

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

Ein "Hacker" könnte Ihren Code ohne die Metadaten von .Net und Java ändern. Jeder erinnert sich an DeHacked http://en.wikipedia.org/wiki/Dehacked Alles, was Sie tun können, hoffen, es so schwer wie möglich zu machen. –

Antwort

27

Zuerst, um Ihre Frage zu beantworten: Das Sicherheitssystem soll GUTE NUTZER von BAD CODE schützen; es ist ausdrücklich nicht entworfen, GOOD CODE von SCHLECHTEN ANWENDER zu schützen.Ihre Zugriffsbeschränkungen mindern Angriffe auf Ihre Benutzer von teilweise vertrauenswürdigen feindlichen Code. Sie mildern nicht Angriffe auf Ihren Code von feindliche Benutzer. Wenn die Bedrohung ist feindliche Benutzer bekommen Ihren Code, dann haben Sie ein großes Problem. Das Sicherheitssystem mindert diese Bedrohung überhaupt nicht.

Zweitens, um einige der vorherigen Antworten zu adressieren: Um die volle Beziehung zwischen Reflexion und Sicherheit verstehen zu können, bedarf es sorgfältiger Details und eines guten Verständnisses der Details des CAS-Systems. Die zuvor geposteten Antworten, die besagen, dass es zwischen Reflexion und Sicherheit keine Verbindung gibt, sind irreführend und falsch.

Ja, mit Reflection können Sie die Sichtbarkeitsbeschränkungen (manchmal) überschreiben. Das bedeutet nicht, dass es keine Verbindung zwischen Zugang und Sicherheit gibt. Die Verbindung besteht darin, dass das Recht, Reflektion zu verwenden, um Zugriffsbeschränkungen außer Kraft zu setzen, in mehrfacher Hinsicht tief mit dem CAS-System verbunden ist.

Zuerst einmal, um dies zu tun beliebig, Code muss private Reflexion Erlaubnis durch das CAS-System gewährt werden. Dies wird normalerweise nur dem vollständig vertrauenswürdigen Code gewährt, der immerhin schon irgendetwas tun könnte.

Zweitens wird im neuen .NET-Sicherheitsmodell angenommen, dass Assembly A vom CAS-System eine Obermenge des Grant-Sets von Assembly B gewährt wird. In diesem Szenario darf Code in Assembly A Reflektion verwenden, um die Interna von B zu beobachten.

Drittens wird es ziemlich kompliziert, wenn Sie dynamisch generierten Code in den Mix einwerfen. Eine Erklärung dafür, wie "Sichtbarkeit überspringen" und "Eingeschränkte Sichtbarkeit überspringen" funktionieren und wie sie die Interaktionen zwischen Reflexion, Zugriffskontrolle und Sicherheitssystem in Szenarien verändern, in denen Code zur Laufzeit gespuckt wird, würde mehr Zeit und Platz beanspruchen als ich verfügbar haben. Siehe Shawn Farkas Blog, wenn Sie Details benötigen.

+1

Wenn ich richtig verstehe, dann Code mit restrictive private/sealed/readonly ist wirklich sicherer, wenn man den potentiell feindlichen Code in sagen, Medium Vertrauen. – MatthewMartin

+1

Korrigieren. Natürlich, wenn der feindliche Code voll und ganz vertrauenswürdig ist, dann ist das Spiel schon vorbei, Mann. Feindliche Vollvertrauens-Codes können einfach alles tun, was sie wollen. Volles Vertrauen bedeutet _full_ trust! –

6

Nein. Diese haben nichts mit Sicherheit zu tun. Die Reflexion bricht sie alle.

+1

Das ist irreführend. Siehe meine Antwort für Details. –

+0

Eric, das OP hat festgelegt, "solange Sie Zugang zu Reflection haben". Gibt es Situationen, in denen Code auf Reflection zugreifen kann, jedoch nicht auf private, interne, geschützte oder geschützte interne Member und Typen zugreifen kann? –

+0

Ja, aber Sie werden fast sicher nicht auf sie stoßen, wenn Sie nicht ein Compiler-Writer sind, der einen Compiler schreibt, der mit Silverlight arbeitet. Es gibt obskure Szenarien mit silverlight, dynamisch generiertem Code aus Ausdrucksbäumen und Compiler-generierten Schließklassen. Wir haben am Silverlight-Sicherheitssystem kleinere Änderungen vorgenommen, um die Probleme zu umgehen, aber es gibt immer noch potenzielle Probleme, die hoffentlich in zukünftigen Versionen behoben werden. –

11

Zugriffsmodifizierer sind nicht über Sicherheit, aber gutes Design. Richtige Zugriffsebenen für Klassen und Methoden treiben gute Designprinzipien voran. Reflektion sollte idealerweise nur dann eingesetzt werden, wenn die Benutzerfreundlichkeit mehr Nutzen bietet als die Kosten für die Verletzung der besten Designpraktiken (falls vorhanden). Sealing-Klassen dienen nur dazu, Entwickler daran zu hindern, Ihre Klasse zu erweitern und ihre Funktionalität zu "brechen". Es gibt verschiedene Meinungen über den Nutzen von Versiegelungsklassen, aber da ich TDD mache und es schwierig ist, eine versiegelte Klasse zu verspotten, vermeide ich es so gut wie möglich.

Wenn Sie Sicherheit wollen, müssen Sie die Kodierungspraktiken befolgen, die verhindern, dass die bösen Jungs hinein kommen und/oder vertrauliche Informationen vor einer Inspektion schützen, selbst wenn es zu einem Einbruch kommt. Intrusion Prevention, Intrusion Detection, Verschlüsselung, Auditing usw. sind einige der Tools, die Sie zum Sichern Ihrer Anwendung einsetzen müssen. Das Einrichten restriktiver Zugriffsmodifizierer und Siegelklassen hat wenig mit der Anwendungssicherheit IMO zu tun.

1

In Bezug auf die Kommentare zu Reflexion und Sicherheit - beachten Sie, dass es viele interne Typen + Mitglieder in mscorlib.dll gibt, die in native Windows-Funktionen aufrufen und möglicherweise zu Schlechtigkeit führen, wenn eine bösartige Anwendung Reflektion verwendet, um sie aufzurufen. Dies ist nicht unbedingt ein Problem, da nicht vertrauenswürdige Anwendungen diese Berechtigungen normalerweise nicht von der Laufzeitumgebung erhalten. Dies (und ein paar deklarative Sicherheitschecks) ist, wie die mscorlib.dll-Binärdatei ihre Typen allen Arten von vertrauenswürdigem und nicht vertrauenswürdigem Code zugänglich machen kann, aber der nicht vertrauenswürdige Code kann die öffentliche API nicht umgehen.

Dies ist wirklich nur die Oberfläche der Reflexion + Sicherheit Problem kratzen, aber hoffentlich ist es genug Informationen, um Sie auf den richtigen Weg zu führen.

1

Ich versuche immer, die Dinge auf den minimalen erforderlichen Zugriff zu sperren. Wie Tvafosson sagte, geht es mehr um Design als um Sicherheit.

Zum Beispiel werde ich eine Schnittstelle öffentlich machen, und meine Implementierungen intern, und dann eine öffentliche Factory-Klasse/Methoden, um die Implementierungen zu bekommen. Dies zwingt die Verbraucher dazu, es immer als Schnittstelle und nicht als Implementierung einzugeben.

Ein Entwickler könnte Reflektion verwenden, um tatsächlich eine neue Instanz eines Implementierungstyps zu instanziieren. Es gibt nichts, was ihn aufhalten könnte. Ich kann mich jedoch darauf verlassen, dass ich es zumindest etwas schwierig gemacht habe, das Design zu verletzen.

Verwandte Themen