Erstellen sicherer Remotekomponenten
Auf dieser Seite
Modulübersicht
Zielsetzung
Betrifft
Verwendung dieses Moduls
Übersicht
Bedrohungen und Gegenmaßnahmen
Überlegungen zum Entwurf
Eingabeüberprüfung
Authentifizierung
Autorisierung
Vertrauliche Daten
Dienstverweigerung
Ausnahmeverwaltung
Überwachen und Protokollieren
Überlegungen zur Codezugriffssicherheit
Zusammenfassung
Weitere Informationen
Modulübersicht
Microsoft® .NET Framework Remoting bietet ein umfangreiches und ausbaufähiges Framework für Objekte, die sich in unterschiedlichen Anwendungsdomänen (AppDomains), in verschiedenen Prozessen und auf verschiedenen Computern befinden, damit diese nahtlos untereinander kommunizieren können. .NET Remoting bietet eine leistungsfähige und einfache Unterstützung für Programmiermodell und Laufzeit, um diese Interaktionen transparent zu machen.
Obwohl die Infrastruktur für den Remotezugriff keine Standard-Authentifizierung oder -Autorisierung beinhaltet, können die Authentifizierungs- und Autorisierungsdienste von ASP.NET und IIS (Internetinformationsdienste) verwendet werden, wenn Remotekomponenten mit ASP.NET gehostet werden und der HttpChannel für die Kommunikation verwendet wird.
Dieses Modul beinhaltet Empfehlungen und Anleitungen, die dabei helfen, sichere Remotekomponenten zu erstellen. Dies schließt Komponenten ein, die ASP.NET und den HttpChannel verwenden, und solche, die benutzerdefinierte ausführbare Dateien und den TcpChannel verwenden.
Zielsetzung
Themenbereiche:
Entwickeln und Bereitstellen von sicheren Komponenten.
Schützen von vertraulichen Daten, die an Remotekomponenten und von diesen zurück übergeben werden.
Wählen eines geeigneten Hostprozesses.
Vergleich des HttpChannel mit dem TcpChannel.
Verringern des Risikos von Serialisierungs- und MarshalByRefObject-Angriffen.
Authentifizieren und Autorisieren von Benutzern.
Verhindern von Dienstverweigerungsangriffen auf Remotekomponenten.
Vorgehensweise in einer nur teilweise vertrauenswürdigen Umgebung, da Remotekomponenten eine vollständige Vertrauenswürdigkeit erfordern.
Wichtige Gegenmaßnahmen bei häufigen Bedrohungen durch Remotezugriff. Zu diesen zählen nicht autorisierter Zugriff, Abhören des Netzwerks und die Manipulation von Parametern.
Betrifft
Die Informationen in diesem Modul gelten für folgende Produkte und Technologien:
Microsoft Windows® 2000 Server und Microsoft Windows Server 2003
Microsoft .NET Framework 1.1 und ASP.NET 1.1
Verwendung dieses Moduls
Empfehlungen für eine erfolgreiche Arbeit mit diesem Modul:
Verwenden Sie dieses Modul in Verbindung mit Modul 17, "Schützen des Anwendungsservers". In Modul 17 wird das Schützen einer Remotelösung auf der mittleren Schicht aus Sicht des Administrators beschrieben.
Siehe "Prüfliste: Schützen des Remotezugriffs" im Abschnitt "Prüflisten" dieses Handbuchs. Hier erhalten Sie eine Zusammenfassung der Sicherheitsmaßnahmen, die für den Aufbau und die Konfiguration von sicheren .NET Framework Remotelösungen erforderlich sind.
Übersicht
Die Microsoft .NET Framework Remoting-Infrastruktur hat keine Standard-Authentifizierungs- oder Autorisierungsmechanismen. Die Authentifizierungs- und Autorisierungsdienste von ASP.NET und IIS können jedoch verwendet werden, wenn die Remotekomponenten mit ASP.NET gehostet werden und der HttpChannel zur Kommunikation verwendet wird.
Bei Leistungsproblemen ist auch ein benutzerdefinierter Host mit dem TcpChannel zu verwenden. Dies sollte allerdings nur in vertrauenswürdigen Subsystemszenarios geschehen, in denen die Spanne möglicher Benutzer sorgfältig gesteuert wird, beispielsweise über IPSec-Richtlinien, die nur die Kommunikation von bestimmten Webservern ermöglichen. Mit dem TcpChannel muss ein eigener Authentifizierungs- und Autorisierungsmechanismus aufgebaut werden. Dies steht im Widerspruch zur Verwendung von bewährten und erprobten Sicherheitsdiensten auf Plattformebene und erfordert einen bedeutenden Entwicklungsaufwand.
In diesem Modul erhalten Sie Empfehlungen und Anleitungen für das Erstellen von sicheren Remotekomponenten. Dies schließt Komponenten ein, die ASP.NET und den HttpChannel verwenden, und solche, die benutzerdefinierte ausführbare Dateien und den TcpChannel verwenden. Das typische Bereitstellungsmuster, von dem in dieses Modul ausgeht, ist in Abbildung 13.1 dargestellt. Remoteobjekte befinden sich hier auf einem Anwendungsserver der mittleren Schicht und verarbeiten Anfragen von ASP.NET-Webanwendungsclients sowie von im Unternehmen bereitgestellten Windows-Anwendungen.
Abbildung 13.1
Typische Bereitstellung für den Remotezugriff
In diesem allgemeinen Szenario bearbeitet die Remotekomponente Anforderungen von Front-End-Webanwendungen. In diesem Fall gewährleistet ASP.NET die Authentifizierung und Autorisierung der Benutzer auf dem Webserver. Zusätzlich greifen Windows-Anwendungen des Unternehmens oft auf Remotekomponenten der mittleren Schicht zu.
Bedrohungen und Gegenmaßnahmen
Um sichere Lösungen mit Remotetechnologien bereitzustellen, müssen die möglichen Bedrohungen bekannt sein. Die größten Bedrohungen für Komponenten, von denen der Remotezugriff verwendet wird, sind:
Nicht autorisierter Zugriff
Abhören des Netzwerks
Parametermanipulation
Serialisierung
In Abbildung 13.2 sind Bedrohungen aufgeführt.
Abbildung 13.2
Hauptbedrohungen durch den Remotezugriff
Nicht autorisierter Zugriff
Remotekomponenten, die vertrauliche oder geheime Informationen zur Verfügung stellen, sollten ihre Benutzer authentifizieren und autorisieren, um einen nicht autorisierten Zugriff zu verhindern. Eine schwache Authentifizierung und Autorisierung kann ausgenutzt werden, um nicht berechtigten Zugriff auf vertrauliche Informationen und Vorgänge zu erhalten.
Sicherheitslücken
Zu den Sicherheitslücken, die Ihre Remotelösung anfällig für nicht autorisierten Zugriff machen, gehören:
Keine Authentifizierung auf Anwendungsebene, da ein benutzerdefinierter Windows-Dienst als Host verwendet wird
Keine IPSec-Richtlinien, die beschränken, welche Computer mit dem Anwendungsservern der mittleren Schicht kommunizieren können, der die Remotekomponenten hostet
Keine rollenbasierte Autorisierung
Keine Dateiautorisierung, um den Zugriff auf Remoting-Endpunkte zu beschränken
Vertrauen in IPrincipal-Objekte, die vom Client weitergeleitet wurden
Gegenmaßnahmen
Gegenmaßnahmen, die implementiert werden können, um einen nicht autorisierten Zugriff zu verhindern:
Es ist sicherzustellen, dass die Front-End-Webanwendung die Clients authentifiziert und autorisiert, und dass die Kommunikation mit Anwendungsservern der mittleren Schicht durch IPSec-Richtlinien beschränkt wird. Diese Maßnahmen gewährleisten, dass nur der Webserver direkt auf den Anwendungsserver der mittleren Schicht zugreifen kann.
Verwenden Sie ASP.NET, um Remotekomponenten zu hosten und die Windows-Authentifizierung, um den Zugriff auf Remotekomponenten zu beschränken.
Verwenden Sie das ASP.NET FileAuthorizationModule. Dies erfordert eine spezifische Konfiguration und das Erstellen einer physischen Datei (.rem oder .soap), um mit dem Remoting-Endpunkt übereinzustimmen.
Verwenden Sie eine rollenbasierte Autorisierung, um den Zugriff auf Remotekomponenten, Remotekoponentenklassen und -methoden zu beschränken. Dies kann über die URL-Autorisierung erfolgen, um den Zugriff auf den Remoting-Endpunkt (.rem oder .soap) zu steuern, oder auf Klassen- oder Methodenebene über Prinzipal-Berechtigungsanforderungen.
Vertrauen Sie keinen IPrincipal-Objekten, die vom Client weitergeleitet werden, es sei denn, der Client ist vertrauenswürdig. Dies ist im Allgemeinen nur der Fall, wenn IPSec verwendet wird, um den Bereich der Clientcomputer zu beschränken.
Abhören des Netzwerks
Durch Abhören des Netzwerks ist ein Angreifer in der Lage, Anforderungs- und Antwortmeldungen anzuzeigen, wenn diese über das Netzwerk zur Remotekomponente und von ihr zurück übertragen werden. Ein Angreifer kann beispielsweise eine Software zur Netzwerküberwachung verwenden, um vertrauliche Daten zu erlangen. Dazu gehören vertrauliche Daten auf Anwendungsebene oder Anmeldeinformationen.
Sicherheitslücken
Zu den Sicherheitslücken, die zur Gefährdung der Sicherheit durch ein Abhören des Netzwerks führen können, gehören:
Die Standardauthentifizierung, die über einen unverschlüsselten Kommunikationskanal verwendet wird
Keine Verschlüsselung auf Transportebene
Keine Verschlüsselung auf Anwendungsebene
Gegenmaßnahmen
Gegenmaßnahmen, die implementiert werden können, um Angriffe durch erfolgreiches Abhören des Netzwerks zu verhindern, umfassen:
Verwendung einer Verschlüsselung auf Transportebene wie SSL oder IPSec. Der Einsatz von SSL erfordert die Verwendung eines ASP.NET-Hosts und von HttpChannel. IPSec kann mit benutzerdefinierten Hosts und TcpChannel verwendet werden.
Verschlüsseln Sie die Anforderung auf Anwendungsebene, um den Datenschutz zu gewährleisten. Sie könnten beispielsweise eine benutzerdefinierte Verschlüsselungssenke erstellen, um einen Teil des ganzen Meldungsinhalts zu verschlüsseln.
Parametermanipulation
Die Parametermanipulation bezieht sich auf die nicht autorisierte Modifizierung von Daten, die zwischen Client und Remotekomponente übertragen werden. Ein Angreifer kann zum Beispiel die Anforderungsmeldung manipulieren, die für die Remotekomponente bestimmt ist, indem er die Meldung abfängt, während sie übertragen wird.
Sicherheitslücken
Folgende Sicherheitslücken können Parametermanipulation zur Folge haben:
Meldungen, die nicht digital signiert sind, um Fälschungssicherheit zu bieten.
Meldungen, die nicht verschlüsselt sind, um Datenschutz und Fälschungssicherheit zu bieten.
Gegenmaßnahmen
Folgenden Gegenmaßnahmen können implementiert werden, um eine erfolgreiche Parametermanipulation zu verhindern:
Digitales Signieren der Meldung. Die digitale Signatur wird auf der Seite des Empfängers verwendet, um sicherzustellen, dass die Meldung während der Übertragung nicht manipuliert wird.
Verschlüsseln Sie den Meldungsinhalt, um Datenschutz und Fälschungssicherheit zu gewährleisten.
Serialisierung
Serialisierung ist die Umwandlung des internen Zustands eines Objekts in einen nicht strukturierten Datenstrom. Die Serialisierungsdienste von .NET Framework werden von der Infrastruktur für den Remotezugriff verwendet, um Objekte zwischen Client und Server zu übertragen. Über bösartigen Code können serialisierte Datenströme in einen Server injiziert werden, um die Durchführung ungewollter Aktionen zu erzwingen. Bösartiger Code von einem Client kann beispielsweise ein Objekt initialisieren. Bei der Deserialisierung dieses Objekts auf dem Server können Serverressourcen verbraucht oder bösartiger Code ausgeführt werden.
Sicherheitslücken
Die hauptsächliche Sicherheitslücke, die zu erfolgreichen Serialisierungsangriffen führen kann, ist dadurch begründet, dass serialisierte Datenströme vom Server als vertrauenswürdig betrachtet und die erhaltenen Daten nicht überprüft werden.
Gegenmaßnahmen
Die Gegenmaßnahme ist, jedes Datenobjekt zu überprüfen, wenn es auf dem Server deserialisiert wird. Überprüfen Sie jedes Feld nach Typ, Länge, Format und Bereich.
Überlegungen zum Entwurf
Bevor Sie mit der Entwicklung von Remotekomponenten beginnen, sind beim Entwurf einige Aspekte zu beachten. Die wichtigsten Überlegungen zur Sicherheit sind:
Remoteobjekte dürfen über das Internet nicht öffentlich zugänglich sein.
Verwenden Sie HttpChannel, um die Vorteile der ASP.NET-Sicherheit zu nutzen.
Verwenden Sie TcpChannel nur in vertrauenswürdigen Serverszenarios.
Verhindern des öffentlichen Zugriffs auf Remoteobjekte über das Internet
Sie sollten Remoteobjekte nur auf Anwendungsservern der mittleren Schicht hosten, auf die nicht direkt über das Internet, sondern nur über Front-End-Webanwendungen und Webdienste zugegriffen werden kann. Wenn es erforderlich ist, Funktionen von Remoteobjekten für Internetclients zur Verfügung zu stellen, verwenden Sie einen Webdienst, der über das Internet zugänglich ist. Somit wird verhindert, dass Benutzer direkt auf das Objekt der mittleren Schicht zugreifen.
Verwenden von HttpChannel, um die Vorteile der ASP.NET-Sicherheit zu nutzen
Verwenden Sie ASP.NET zum Hosten von Remoteobjekten, wenn die Sicherheit Ihr wichtigstes Anliegen ist. Dadurch können Sie Funktionen zur Authentifizierung, Autorisierung und sicheren Kommunikation verwenden, die von ASP.NET und IIS zur Verfügung gestellt werden. Sie können zum Beispiel die Authentifizierung von Windows und SSL verwenden, um Datenschutz zu gewährleisten, sowie die Integrität von Anforderungen und Antworten sicherzustellen, die über das Netzwerk verschickt werden.
Verwenden von TcpChannel in vertrauenswürdigen Serverszenarios
Wenn TcpChannel aus Leistungsgründen mit einem benutzerdefinierten Hostprozess verwendet wird, muss gesichert sein, dass keine eingebauten Authentifizierungsdienste vorhanden sind.
Aus diesem Grund sollte TcpChannel nur in vertrauenswürdigen Serverszenarios verwendet werden, bei denen die Upstream-Webanwendung oder der Webdienst die ursprünglichen Benutzer authentifiziert und autorisiert, bevor sie die Remotekomponenten der mittleren Schicht aufruft. Um dieses Szenario zu sichern, ist IPSec für Authentifizierung und sichere Kommunikation auf Computerebene zu verwenden. Über die IPSec-Richtlinie sollte nur Datenverkehr von den festgelegten Webservern zum Host für Remotekomponenten der mittleren Schicht ermöglicht werden. Dieses vertrauenswürdige Serverszenario wird in Abbildung 13.3 dargestellt.
Abbildung 13.3
Remotezugriff in einem vertrauenswürdigen Serverszenario
Weitere Informationen über IPSec finden Sie unter "Verwenden von IPSec für das Filtern von Ports und die Authentifizierung" im entsprechenden Abschnitt dieses Handbuchs.
Überlegungen zum TcpChannel
Wenn ein benutzerdefinierter Host und der TcpChannel verwendet werden und Sie sich nicht auf eine Upstream-Webanwendung für die Clientauthentifizierung und -autorisierung verlassen können, müssen Sie eigene Authentifizierungs- und Autorisierungslösungen entwickeln.
Als Teil einer benutzerdefinierten Lösung können Prinzipal-Objekte als Parameter für Methoden oder im Aufrufkontext übergeben werden. Dies sollte nur in einer vertrauenswürdigen Umgebung geschehen, um zu verhindern, dass durch bösartigen Code vom Client ein IPrincipal-Objekt mit erweiterten Rollen erstellt und an den Server gesendet wird. Über die Serverimplementierung muss sichergestellt werden, dass IPrincipal-Objekten vertraut werden kann, bevor diese für rollenbasierte Autorisierung verwendet werden.
Wahlweise können die zugrunde liegenden Dienste der Sicherheitsunterstützungs-Anbieterschnittstelle verwendet werden. Weitere Informationen über diesen Ansatz finden Sie im MSDN-Artikel ".NET Remoting Security Solution, Part 1: Microsoft.Samples.Security.SSPI Assembly" unter https://msdn.microsoft.com/library/en-us/dndotnet/html/remsspi.asp.
Für eine sichere Kommunikation bei Verwendung von TcpChannel ist IPSec oder eine benutzerdefinierte Verschlüsselungskanalsenke zu verwenden, um die angefragten Daten zu verschlüsseln.
Eingabeüberprüfung
In vertrauenswürdigen Serverszenarios, in denen Remotelösungen verwendet werden sollten, führen Front-End-Webanwendungen üblicherweise Eingabeüberprüfung durch. Die Daten werden vollständig überprüft, bevor sie an die Remotekomponenten weitergegeben werden. Wenn sichergestellt werden kann, dass Daten, die zu Remotekomponenten übertragen werden, ihren Ursprung nur innerhalb der Vertrauensgrenzen haben, startet der Upstreamcode die Eingabeüberprüfung.
Wenn jedoch auf die Remotelösung von beliebigen Clientanwendungen zugegriffen werden kann, die im Unternehmen ausgeführt werden, sollten Eingaben von den Remotekomponenten überprüft und auf Serialisierungs- und MarshalByRefObject-Angriffe geachtet werden.
Serialisierungsangriffe
Objektparameter können an Remotekomponenten entweder über den Aufrufkontext oder durch reguläre Eingabeparameter an die Methoden übergeben werden, die durch die Remotekomponente zugänglich sind. Es ist einem bösartigen Client möglich, ein Objekt zu serialisieren und es dann an eine Remotekomponente zu übertragen, um einen Fehler zu verursachen oder die Durchführung eines nicht beabsichtigten Vorgangs auszulösen. Wenn dem Client nicht vertraut werden kann, sollte jedes Feld im deserialisierten Objekt sorgfältig überprüft werden, da der Objektparameter auf dem Server erzeugt wurde.
MarshalByRefObject-Angriffe
Objekte, die von System.MarshalByRefObject abgeleitet sind, erfordern einen URL, um Rückrufe zum Client durchzuführen. Es ist möglich, den Rückruf-URL so zu manipulieren, so dass sich der Server mit einem anderen Clientcomputer verbindet, beispielsweise einem Computer hinter einer Firewall.
Die Gefahr durch Serialisierungs- und MarshalByRefObject-Angriffe kann mit Version 1.1 des .NET Framework verringert werden, indem das Attribut typeFilterLevel im Element <formatter> auf Low gesetzt wird. Dadurch wird festgelegt, dass von der Infrastruktur für den Remotezugriff des .NET Framework nur Objekte serialisiert werden, die für den Methodenaufruf erforderlich sind, und dass sämtliche benutzerdefinierten, serialisierbaren Objekte, die Sie erstellen und über den Aufrufkontext oder als Parameter übergeben, zurückgewiesen werden. Diese Einstellung kann in Web.config oder per Programm wie unten gezeigt konfiguriert werden.
<formatter ref="binary" typeFilterLevel="Low" />
oder
BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider(); provider.TypeFilterLevel = TypeFilterLevel.Low;
Authentifizierung
Wenn durch eine Remotekomponente vertrauliche Daten öffentlich zugänglich sind, müssen Benutzer authentifiziert werden, um eine Autorisierung zu unterstützen. Durch die Infrastruktur für den Remotezugriff des .NET Framework wird kein Authentifizierungsmodell definiert. Der Host sollte die Authentifizierung durchführen. Sie können zum Beispiel ASP.NET verwenden, um die Vorteile der Authentifizierungsfunktionen von ASP.NET und IIS zu nutzen.
Wenn Sie einen benutzerdefinierten Windows-Diensthost verwenden, müssen Sie eine benutzerdefinierte Authentifizierungslösung entwickeln.
ASP.NET-Hosting
Die folgenden Richtlinien gelten für die Verwendung des ASP.NET-Hosts mit dem HttpChannel:
Schalten Sie die anonyme Authentifizierung in IIS ab.
Konfigurieren Sie ASP.NET für die Windows-Authentifizierung.
Konfigurieren Sie die Client-Anmeldeinformationen.
Erhöhen Sie die Leistung mit der gemeinsamen Nutzung von authentifizierten Verbindungen.
Zwingen Sie Clients, sich bei jedem Aufruf zu authentifizieren.
Steuern Sie die Verwendung von authentifizierten Verbindungen.
Deaktivieren der anonymen Authentifizierung in IIS
Um sicherzustellen, dass Benutzer durch IIS authentifiziert werden, muss klar sein, dass das virtuelle Verzeichnis der Anwendung keine anonyme Authentifizierung unterstützt. Unter Windows Server 2003 muss auch die .NET Passport-Authentifizierung deaktiviert sein.
Da die anonyme Authentifizierung von IIS deaktiviert ist, können sämtliche unterstützte Authentifizierungsmechanismen von IIS verwendet werden, um Benutzer über den HttpChannel zu authentifizieren, zum Beispiel Basic, Digest und die integrierte Windows-Authentifizierung. Um zu vermeiden, dass Anmeldeinformationen über das Netzwerk weitergeleitet werden, und um die Windows 2000 Sicherheitskonten und Kennwortrichtlinien zu nutzen, sollte die integrierte Windows-Authentifizierung verwendet werden.
Konfigurieren von ASP.NET für die Windows-Authentifizierung
Konfigurieren Sie Ihre Anwendung über die folgende Einstellung in Web.config für die Windows-Authentifizierung:
<authentication mode="Windows" />
Die Passport- oder Forms-Authentifizierung kann nicht verwendet werden, da diese eine Umleitung auf eine Anmeldeseite erfordern.
Hinweis: Wenn die Windows-Authentifizierung verwendet wird, ist es empfehlenswert, die Dateiautorisierung zu aktivieren. Weitere Informationen finden Sie unter "Autorisierung" weiter unten in diesem Modul.
Konfigurieren der Client-Anmeldeinformationen
Um erfolgreich mit einer Remotekomponente zu kommunizieren, die für Windows-Authentifizierung konfiguriert ist, muss der Client den Remoteproxy mit den für die Authentifizierung zu verwendenden Anmeldeinformationen konfigurieren. Unterbleibt diese Aktion, ergibt dies den Fehler Zugriff verweigert.
Die Verwendung der Standardanmeldeinformationen kann konfiguriert werden, um das aktuelle Thread- oder Prozesstoken des Client zu verwenden, oder es können explizite Anmeldeinformationen eingestellt werden.
Verwenden von Standardanmeldeinformationen
Um das Prozesstoken des Client zu verwenden (oder das Threadtoken, wenn der Client Thread gerade personifiziert), ist die Eigenschaft useDefaultCredentials des Clientproxy auf true zu setzen. Dies resultiert in der Verwendung von CredentialsCache.DefaultCredentials, wenn der Client eine Authentifizierungsherausforderung vom Server erhält. Der Proxy kann entweder mittels der Konfigurationsdatei oder per Programmcode konfiguriert werden. Um den Proxy extern zu konfigurieren, ist das folgende Element in der Konfigurationsdatei des Client zu verwenden:
<channel ref="http client" useDefaultCredentials="true" />
Um die Standardanmeldeinformationen per Programm einzustellen, ist der folgende Code zu verwenden:
IDictionary channelProperties; channelProperties = ChannelServices.GetChannelSinkProperties(proxy); channelProperties ["credentials"] = CredentialCache.DefaultCredentials;
Wenn Standardanmeldeinformationen in einer ASP.NET-Clientanwendung verwendet werden, die für Personifizierung konfiguriert ist, wird das Thread-Level Personifizierungstoken verwendet. Dies erfordert eine Kerberos-Delegierung.
Verwenden von alternativen Anmeldeinformationen
Um einen spezifischen Satz von Anmeldeinformationen für die Authentifizierung beim Aufruf eines Remoteobjekts zu verwenden, ist die Verwendung von Standardanmeldeinformationen innerhalb der Konfigurationsdatei unter Verwendung folgender Einstellungen zu deaktivieren.
<channel ref="http" useDefaultCredentials="false" />
Hinweis: Programmierte Einstellungen haben immer Vorrang vor den Einstallungen in der Konfigurationsdatei.
Zur Konfiguration des Proxy für die Verwendung spezifischer Anmeldeinformationen ist der folgende Code zu verwenden:
IDictionary channelProperties = ChannelServices.GetChannelSinkProperties(proxy); NetworkCredential credentials; credentials = new NetworkCredential("username", "password", "domain"); ObjRef objectReference = RemotingServices.Marshal(proxy); Uri objectUri = new Uri(objectReference.URI); CredentialCache credCache = new CredentialCache(); // Ersetzen Sie "authenticationType" mit "Negotiate", "Basic", "Digest", // "Kerberos" oder "NTLM" credCache.Add(objectUri, "authenticationType", credentials); channelProperties["credentials"] = credCache; channelProperties["preauthenticate"] = true;
Erhöhen der Leistung über die gemeinsame Nutzung von authentifizierten Verbindungen
Wenn useDefaultCredentials="true" gesetzt wird, sollte auch die Eigenschaft useAuthenticatedConnectionSharing auf Clientseite auf true gesetzt werden Dies ermöglicht dem Server die Wiederverwendung von authentifizierten Verbindungen anstatt jeden eingehenden Aufruf zu authentifizieren.
<channel ref="http client" useAuthenticatedConnectionSharing="true" >
Diese Funktion ist nur mit dem HttpChannel in Version 1.1 des .NET Framework verfügbar.
Erzwingen der Authentifizierung von Clients bei jedem Aufruf
Setzen Sie unsafeAuthenticatedConnectionSharing auf false, so dass Clients nicht in der Lage sind, ihre eigenen Anmeldeinformationen und Verbindungsgruppennamen auf dem Server anzugeben.
Wenn Sie den Wert auf true setzen, können sich nicht authentifizierte Clients möglicherweise auf dem Server authentifizieren, indem sie die Anmeldeinformationen eines vorher authentifizierten Clients verwenden. Diese Einstellung wird ignoriert, wenn die Eigenschaft useAuthenticatedConnectionSharing auf true gesetzt wird. Diese Einstellung hat Auswirkungen auf die Leistung, da jede Verbindung mit dem Server beendet wird und Clients bei jedem Aufruf authentifiziert werden müssen. Wenn diese Einstellung verwendet wird, sollte auch ein ConnectionGroupName für jeden Benutzer dieser Verbindung angegeben werden.
<channel ref="http client" unsafeAuthenticatedConnectionSharing="false" >
Diese Funktion ist nur mit dem HttpChannel in Version 1.1 von .NET Framework verfügbar.
Steuern von authentifizierten Verbindungen
Wenn unsafeAuthenticationConnectionSharing auf true gesetzt wird, sollte ein Name angegeben werden, um die authentifizierten Verbindungen durch Einstellen der Eigenschaft connectionGroupName zusammen zu gruppieren. Wenn Standardanmeldeinformationen verwendet werden, beruht connectionGroupName auf dem Benutzerkonto, das für die Ausführung des Threads verwendet wird.
<channel ref="http client" connectiongroupname="<name>" />
Benutzerdefiniertes Prozess-Hosting
Wenn ein Windows-Diensthost und der TcpChannel verwendet werden, ist entweder dieser Ansatz nur in einem vertrauenswürdigen Serverszenario zu nutzen, oder ein benutzerdefiniertes Authentifizierungsschema zur Verfügung zu stellen. Die folgenden Richtlinien gelten für die Verwendung eines benutzerdefinierten Hosts mit dem TcpChannel:
Senden Sie keine Anmeldeinformationen im Klartext über das Netzwerk.
Vertrauen Sie keinen Iprincipal-Objekten, die vom Client weitergeleitet wurden.
Keine Anmeldeinformationen im Klartext über das Netzwerk senden
Wenn ein Server die Anmeldeinformationen des Client im Klartext benötigt, sind diese zu verschlüsseln, bevor sie über das Netzwerk gesendet werden. Wenn es ein Server erfordert, die Anmeldeinformationen eines Client zu überprüfen, sollte ein Herausforderung/Antwort-Schema verwendet werden, um die Anmeldeinformationen auf dem Server zu überprüfen. Dies könnte das Senden eines Hash, verschlüsselten Hash, einer Ad-Hoc-Bildung, welche mit dem Hash verschlüsselt ist oder die Verwendung einer digitalen Signatur umfassen.
Jedoch sollten Sie auch in diesen Szenarios einen verschlüsselten Kommunikationskanal verwenden, um die Wiederholung von Angriffen zu verhindern.
Keinen Iprincipal-Objekten, die vom Client übertragen wurden, vertrauen
Beim Weiterleiten von IPrincipal-Objekten vom Client zum Server sollten Sie vorsichtig sein. Nicht vertrauenswürdiger Code kann ein IPrincipal-Objekt erzeugen, es mit Rollen initialisieren und es dann an den Server senden. Wenn der Server das IPrincipal ohne Überprüfung annimmt, kann der Client die Berechtigungen des Benutzers auf dem Server erhöhen. Es könnte zum Beispiel ein bösartiger Benutzer ein IPrincipal-Objekt erstellen, das allgemeine Rollennamen mit hohen Berechtigungen, wie Administratoren, Manager, ExpenseReportApprovers und Supervisors, enthält. Wenn das Objekt beim Server ankommt und in der Eigenschaft Thread.CurrentPrincipal plaziert ist, kann sich Code, der IsInRole auf diesem Objekt aufruft, täuschen lassen, privilegierten Code auszuführen.
Autorisierung
Innerhalb des Kontexts von .NET Framework Remoting kann die Autorisierung angewendet werden, um die Fähigkeit von Computern und Benutzern zu beschränken, auf Funktionen zuzugreifen, die von Remoteobjekten exponiert werden. Verwenden Sie die folgenden Richtlinien für einen effektiven Autorisierungsansatz:
Verwenden Sie IPSec für die Zugriffssteuerung auf Computerebene.
Aktivieren Sie die Dateiautorisierung für die Benutzerzugriffssteuerung.
Autorisieren Sie Benutzer über prinzipalbasierte Rollenprüfungen.
Bedenken Sie die Beschränkung des Remotezugriffs.
Verwenden von IPSec für die Zugriffssteuerung auf Computerebene
Eine IPSec-Richtlinie dient dazu, dass sich nur ein genannter Webserver oder Servercluster mit dem Anwendungsserver verbinden kann, der die Remoteobjekte hostet. Dies reduziert die Angriffsoberfläche bedeutend.
Aktivieren der Dateiautorisierung für die Benutzerzugriffssteuerung
Wenn das Remoteobjekt von ASP.NET gehostet und die Windows-Authentifizierung verwendet wird, können die Windows-Zugriffssteuerungslisten auf den Remoting-Endpunkten konfiguriert werden, um Benutzer zu autorisieren. Zugriffsteuerungslisten werden pro Anforderung durch das ASP.NET-Modul FileAuthorizationModule ausgewertet. Unter normalen Umständen existiert keine physikalische Datei, welche die Remoting-Endpunkte darstellt, mit denen die Clients verbinden. Die Anforderung einer Datei mit der Dateinamenerweiterung .rem oder .soap genügt, damit sie von IIS anhand der Anwendungszuordnungen in der IIS-Metabasis zur geeigneten ASP.NET-Anwendung geroutet werden kann.
Konfigurieren des ASP.NET FileAuthorizationModule für .NET Framework Remoting
Erstellen Sie eine Datei, deren Name dem Wert der Eigenschaft objectUri in Web.config entspricht, beispielsweise RemoteMath.rem im Stammverzeichnis des virtuellen Verzeichnisses der Anwendung.
Sie können den Wert von objectUri in der Datei Web.config herausfinden, die für die Konfiguration des Remoteobjekts auf dem Server verwendet wird. Suchen Sie nach dem Element <wellknown>, wie im folgenden Beispiel angegeben:<wellknown mode="SingleCall" objectUri="RemoteMath.rem" type="RemotingObjects.RemoteMath, RemotingObjects, Version=1.0.000.000 Culture=neutral, PublicKeyToken=4b5ae668c251b606"/>
Schreiben Sie die folgende Zeile an den Anfang der Datei und speichern Sie diese.
<%@ webservice class="IhrNamespace.IhreKlasse" ... %>
Fügen Sie eine entsprechend konfigurierte Zugriffssteuerungsliste mit Windows Explorer zur Datei hinzu, um festzulegen, welche Benutzer oder Benutzergruppen auf das Objekt zugreifen können.
Autorisieren von Benutzern über prinzipalbasierte Rollenprüfungen
Über den oben beschriebenen Ansatz FileAuthorizationModule kann festgelgt werden, wer auf das Remoteobjekt zugreifen kann und wer nicht. Für eine feinstufige Autorisierung, die auf Methodenebene angewendet werden kann, können Autorisierungsprüfungen mithilfe des Objekts IPrincipal durchgeführt werden, das an die aktuelle Anfrage angehängt ist.
Wird das Remoteobjekt von ASP.NET gehostet und die Windows-Authentifizierung verwendet, wird ein IPrincipal-Objekt, das auf der authentifizierten Windows-Identität des Benutzers beruht, automatisch erzeugt und an Thread.CurrentPrinicipal angehängt.
Wenn ein benutzerdefinierter Host verwendet wird, ist ein IPrincipal-Objekt zu erstellen, um den authentifizierten Benutzer darzustellen. Die Mechanismen sind von der Authentifizierungsmehtode abhängig. Wenn beispielsweise ein Named-Pipe-Transport verwendet wird, kann der Benutzer personifiziert werden, um dessen Identität zu erhalten und ein IPrincipal-Objekt zu konstruieren.
Mit dem IPrincipal-Objekt ist eine Autorisierung mithilfe von Prinzipal-Berechtigungsanforderungen sowohl deklarativ als auch imperativ möglich, zudem kann IPrincipal.IsInRole kann aufgerufen werden.
Überlegungen zur Beschränkung des Remotezugriffs
In einigen Szenarios, bei denen der Remotezugriff für die Kommunikation zwischen Prozessen oder über Anwendungsdomänen auf einem einzelnen Computer verwendet wird, kann wie unten gezeigt rejectRemoteRequests auf true gesetzt werden, um sicherzustellen, dass auf das Objekt nicht von Remotecomputern zugegriffen werden kann.
<channel ref="http server" rejectRemoteRequests="true" />
Vertrauliche Daten
Wenn es notwendig ist, vertrauliche Daten über einen Remote-Kommunikationskanal im Netzwerk zu übertragen, müssen Sie die Vertraulichkeit und die Integrität der Daten berücksichtigen, um geeignete Maßnahmen gegen das Abhören des Netzwerks zu treffen. Es gibt drei Auswahlmöglichkeiten, die hauptsächlich von der Bereitstellungsumgebung und der Wahl des Hosts abhängig sind:
Verwenden von IPSec
Verwenden von SSL
Verwenden einer benutzerdefinierten Verschlüsselungssenke
Verwenden von IPSec
Es können IPSec-Richtlinien verwendet werden, um die Kommunikationskanäle zu den Remoteobjekten zu sichern, wie zum Beispiel den Kanal von einem Webserver. IPSec kann verwendet werden, um sämtliche über eine bestimmte Verbindung gesendete TCP-Pakete zu verschlüsseln. Das beinhaltet auch Pakete, die zu und von Remoteobjekten übertragen werden. Diese Lösung wird üblicherweise von sicheren Internet- und Intranet-Datencenter-Infrastrukturen verwendet, und ist nützlich, da kein zusätzlicher Codierungsaufwand notwendig ist.
Der zusätzliche Nutzen von IPSec: Es bietet eine sichere Kommunikationslösung ungeachtet des Remoteobjekthosts und Kanaltyps. Die Lösung funktioniert zum Beispiel, wenn TcpChannel und ein benutzerdefinierter Host verwendet werden.
Verwenden von SSL
Beim ASP.NET-Host können Sie IIS verwenden, um das virtuelle Verzeichnis der Anwendung zu konfigurieren, so dass SSL notwendig ist. Clients müssen anschließend eine HTTPS-Verbindung nutzen, um mit dem Remoteobjekt zu kommunizieren.
Verwenden einer benutzerdefinierten Verschlüsselungssenke
Wenn kein sicheres Datencenter mit IPSec-Richtlinien vorhanden ist, das die Kommunikationskanäle zwischen den Servern sichert, können Sie alternativ eine benutzerdefinierte Verschlüsselungssenke implementieren. Diese Option kann auch in Betracht gezogen werden, wenn es notwendig ist, nur die vertraulichen Teile einer Meldung zu sichern, die vom Client zum Server geleitet wird, anstatt den gesamten Inhalt. Dieser Ansatz wird in Abbildung 13.4 dargestellt.
Abbildung 13.4
Verwenden von benutzerdefinierten Verschlüsselungssenken
Eine Verschlüsselungssenke ist eine benutzerdefinierte Kanalsenke, die verwendet werden kann, wenn ein benutzerdefinierter Host mit dem TcpChannel im Einsatz ist. Auf der Clientseite verschlüsselt die Senke Anfragedaten, bevor diese an den Server gesendet werden und entschlüsselt alle verschlüsselten Daten, die vom Server empfangen werden. Auf der Serverseite entschlüsselt die Senke die Anfragedaten und verschlüsselt dann die Antwortdaten.
Implementieren einer benutzerdefinierten Verschlüsselungssenke
Die Senke sollte eine asymmetrische Verschlüsselung verwenden, um Verschlüsselungsschlüssel auf Sitzungsebene auszutauschen. Nach dem Austausch eines Sitzungsschlüssels behalten Client und Server eine Kopie des Schlüssels. An beiden Enden kann jederzeit während der Gültigkeitsdauer der Kanalsenke ein neuer Schlüssel erstellt werden. Der Server sollte für jeden Client, mit dem er kommuniziert, einen verschiedenen Schlüssel behalten.
Die folgenden Schritte skizzieren den grundlegenden Ansatz, um eine benutzerdefinierte Verschlüsselungssenke zu implementieren:
Erstellen Sie ein Paar aus öffentlichem und privatem Schlüssel für die Lösung.
const int AT_KEYEXCHANGE = 1; CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = "<container name>"; cspParams.KeyNumber = AT_KEYEXCHANGE; cspParams.ProviderName = "Microsoft Base Cryptographic Provider v1.0"; cspParams.ProviderType = PROV_RSA_FULL; RSACryptoServiceProvider rsaServerSide = new RSACryptoServiceProvider(cspParams); rsaServerSide.PersistKeyInCsp = true; Console.WriteLine(rsaServerSide.ToXmlString(true)); // Schreibt den öffentlichen Schlüssel
Veröffentlichen Sie den öffentlichen Schlüssel zum Nutzen der Clients.
Der Client behält eine Kopie des öffentlichen Schlüssels in einer Datei.Initialisieren Sie die Clientkanalsenke, und erstellen Sie einen zufälligen Schlüssel für die Verschlüsselung.
byte[] randomKey = new byte[size]; RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); rng.GetBytes(randomKey);
Verschlüsseln Sie den zufälligen Schlüssel mit dem öffentlichen Schlüssel Ihres Servers. Verwenden Sie IClientChannelSink.ProcessMessage, um den verschlüsselten Schlüssel an den Server zu senden.
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp); rsa.FromXmlString("<server's public key>"); AsymmetricKeyExchangeFormatter formatter = new RSAPKCS1KeyExchangeFormatter(rsa); byte[] encryptedSessionKey = formatter.CreateKeyExchange(_sessionKey);
Initialisieren Sie die Serverkanalsenke, und erstellen Sie ein RSA-Objekt unter Verwendung des spezifischen Schlüsselcontainernamens.
const int AT_KEYEXCHANGE = 1; CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = "<container name>"; cspParams.KeyNumber = AT_KEYEXCHANGE; cspParams.ProviderName = "Microsoft Base Cryptographic Provider v1.0"; cspParams.ProviderType = PROV_RSA_FULL; RSACryptoServiceProvider rsaServerSide = new RSACryptoServiceProvider(cspParams);
Holen Sie den verschlüsselten Schlüssel vom Client. Dieser Schlüssel wird normalerweise im Header der Anforderung gesendet.
Entschlüsseln Sie den Verschlüsselungsschlüssel der Sitzung mithilfe des privaten Schlüssels des Servers.
AsymmetricKeyExchangeDeformatter asymDeformatter = new RSAPKCS1KeyExchangeDeformatter(_rsa); byte[] decryptedSessionKey = asymDeformatter.DecryptKeyExchange( <encrypted key>);
Verwenden Sie einen Mechanismus zur Zuordnung von Clients zu Verschlüsselungsschlüsseln, beispielsweise durch Verwenden einer Hashtabelle.
An diesem Punkt teilen sich sowohl der Client als auch der Server einen Verschlüsselungsschlüssel und können Methodenaufrufe verschlüsseln und entschlüsseln. Während der Lebenszeit des Objekts können und sollten neue Schlüssel regelmäßig erstellt werden.
Dienstverweigerung
Dienstverweigerungsangriffe können auftreten, wenn ein bösartiger Client mehrere Objekte erstellt und deren Gültigkeitsdauer erneuert, um Serverressourcen zu verbrauchen. Remoteobjekte auf dem Server enthalten eine Standardfrist. In diesem Zustand kann ein Client damit fortfahren, die Frist andauernd zu erneuern. Es kann jedoch die Schnittstelle ILease auf dem Server implementiert und Sponsoren und Erneuerungen explizit geregelt werden. Um dies zu tun, ist der InitializeLifetimeService auf dem Objekt MarshalByRefObject außer Kraft zu setzen. Diese Methode wird bei der Erstellung des Objekts von der Infrastruktur für den Remotezugriff aufgerufen. Die Frist kann auch per Programm unter Verwendung des Elements <lifetime> eingestellt werden.
Ausnahmeverwaltung
Vergewissern Sie sich, dass sie nicht die vollen Ausnahmeinformationen an den Benutzer zurückgeben. Wenn Sie einen ASP.NET-Host verwenden, vergewissern Sie sich, dass ASP.NET so konfiguriert ist, dass allgemeine Fehlermeldungen an den Client zurückgegeben werden, wie es unten gezeigt wird.
<configuration> <system.runtime.remoting> <!-- Valid values for mode attribute are on - callers receive default error messages remoteOnly - clients on the same computer as the remote component receive detailed exception information. Remote calls receive a default error message off - callers receive detailed exception information --> <customErrors mode="on"/> </system.runtime.remoting> </configuration>
Verwenden Sie mode="on" oder mode="remoteOnly". Verwenden Sie nicht mode="off" auf Produktionsservern.
Verwenden einer benutzerdefinierten Kanalsenke
Eine benutzerdefinierte Kanalsenke kann implementiert werden, um die Ausnahmeprotokollierung auf Client und Server durchzuführen. Ausnahmeinformationen können in den MethodenSyncProcessMessage, ProcessMessage oder SyncProcessMessage protokolliert werden, wenn eine Ausnahme auftritt. Die Parameter IMessage und Exception stellen Ausnahmeinformationen zur Verfügung.
Überwachen und Protokollieren
Wenn der ASP.NET-Host verwendet wird, können Sie die Überwachungs- und Protokollierungsfunktionen von IIS verwenden. Wenn ein benutzerdefinierter Host verwendet wird, ist eine benutzerdefinierte Überwachung zu implementieren. Dazu kann auch eine benutzerdefinierte Kanalsenke verwendet werden.
Verwenden einer benutzerdefinierten Kanalsenke
Eine benutzerdefinierte Kanalsenke kann implementiert werden, um die Überwachung auf Client und Server durchzuführen. Informationen erhalten Sie aus den MethodenSyncProcessMessage, ProcessMessage oder SyncProcessMessage .
Überlegungen zur Codezugriffssicherheit
Remoteclients erfordern volle Vertrauenswürdigkeit in Version 1.0 und 1.1 des .NET Framework. Die Assembly System.Runtime.Remoting.dll ist nicht mit AllowPartiallyTrustedCallersAttribute markiert.
Um über den Remotezugriff eine Remotekomponente von teilweise vertrauenswürdigem Code aufzurufen, müssen eine voll vertrauenswürdige Wrapperassembly erstellt und die Methodenaufrufe des Remoteobjekts innerhalb einer Sandbox ausgeführt werden. Weitere Informationen über das Sandbox-Prinzip und die Verwendung von Wrapperassembys finden Sie in Modul 9, "Verwenden der Codezugriffssicherheit mit ASP.NET".
Zusammenfassung
Die Infrastruktur für das .NET Framework Remoting wurde für die Verwendung in vertrauenswürdigen Serverszenarios entwickelt, bei denen Benutzer auf vertrauenswürdige Clients beschränkt werden können, beispielsweise durch die Verwendung von IPSec-Sicherheitsrichtlinien. Wenn ein ASP.NET-Host und der HttpChannel im Einsatz ist, ist es ratsam, die darunterliegenden Sicherheitsfunktionen zu verwenden, die von ASP.NET und IIS zur Verfügung gestellt werden. Wenn ein benutzerdefinierter Host und der TcpChannel verwendet werden, möglicherweise aus Leistungsgründen, muss eine eigene Authentifizierungs- und Autorisierungslösung implementiert werden. IPSec kann in diesen Szenarios hilfreich sein, da es eine Authentifizierung auf Computerebene und eine sichere Kommunikation zur Verfügung stellt.
Weitere Informationen
Weitere Informationen finden Sie unter:
Eine druckbare Prüfliste finden Sie unter "Prüfliste: Schützen des Remotezugriffs" im Abschnitt "Prüflisten" dieses Handbuchs.
Weitere Informationen über das Hosten einer Remotekomponente in einem Windows-Dienst finden Sie unter "How To: Host a Remote Object in a Windows Service" im Abschnitt "How To" von "Microsoft patterns & practices Volume I, Building Secure ASP.NET Web Applications: Authentication, Authorization, and Secure Communication" unter https://msdn.microsoft.com/library/en-us/dnnetsec/html/SecNetHT15.asp.
Weitere Informationen über die Erstellung einer benutzerdefinierten Authentifizierungslösung, die SSPI verwendet, finden Sie im MSDN Artikel ".NET Remoting Security Solution, Part 1: Microsoft.Samples.Security.SSPI Assembly" unter https://msdn.microsoft.com/library/en-us/dndotnet/html/remsspi.asp.
Hinweis: Die Implementierung in diesem Artikel ist ein Beispiel und kein Produkt, das von Microsoft getestet und unterstützt wird.