Sicherheitsüberlegungen zu DatenSecurity Considerations for Data

Beim Umgang mit Daten in der Windows Communication Foundation (WCF) müssen Sie eine Reihe verschiedener Bedrohungen berücksichtigen.When dealing with data in Windows Communication Foundation (WCF), you must consider a number of threat categories. In der folgenden Tabelle werden die wichtigsten Bedrohungskategorien der Datenverarbeitung aufgeführt.The following table lists the most important threat classes that relate to data processing. WCF bietet Tools zu deren Abwehr.WCF provides tools to mitigate these threats.

Denial-of-Service-AngriffeDenial of service
Der Erhalt nicht vertrauenswürdige Daten kann aufgrund langwieriger Berechnungen auf Empfängerseite einen überdurchschnittlich hohen Zugriff auf verschiedene Ressourcen, wie Arbeitsspeicher, Threads, verfügbare Verbindungen oder Prozessorzyklen verursachen.When receiving untrusted data, the data may cause the receiving side to access a disproportionate amount of various resources, such as memory, threads, available connections, or processor cycles by causing lengthy computations. Ein Denial-of-Service-Angriff führt möglicherweise zum Absturz des Servers, wodurch er keine Nachrichten von anderen, legitimen Clients verarbeiten kann.A denial-of-service attack against a server may cause it to crash and be unable to process messages from other, legitimate clients.

Ausführung von schädlichem CodeMalicious code execution
Eingehende nicht vertrauenswürdige Daten bewirken, dass die Empfängerseite unbeabsichtigten Code ausführt.Incoming untrusted data causes the receiving side to run code it did not intend to.

Offenlegung vertraulicher InformationenInformation disclosure
Der Remoteangreifer zwingt die Empfängerseite, auf Anforderungen so zu antworten, dass dabei mehr Informationen als beabsichtigt offengelegt werden.The remote attacker forces the receiving party to respond to its requests in such a way as to disclose more information than it intends to.

Vom Benutzer bereitgestellter Code und CodezugriffssicherheitUser-Provided Code and Code Access Security

Eine Anzahl von Stellen in der Windows Communication Foundation (WCF)-Infrastruktur wird Code, der vom Benutzer bereitgestellt wird ausgeführt.A number of places in the Windows Communication Foundation (WCF) infrastructure run code that is provided by the user. Das Serialisierungsmodul DataContractSerializer z. B. kann vom Benutzer bereitgestellte set - und get -Eigenschaftenaccessoren aufrufen.For example, the DataContractSerializer serialization engine may call user-provided property set accessors and get accessors. Der WCF--Kanalinfrastruktur ruft möglicherweise auch vom Benutzer bereitgestellte abgeleiteten Klassen von der Message Klasse.The WCF channel infrastructure may also call into user-provided derived classes of the Message class.

Der Autor des Codes muss sicherstellen, dass kein Sicherheitsrisiko entsteht.It is the responsibility of the code author to ensure that no security vulnerabilities exist. Angenommen, Sie erstellen einen Datenvertragstyp mit einer Datenmembereigenschaft vom Typ Integer und ordnen in der Implementierung des set -Accessors basierend auf dem Eigenschaftswert ein Array zu. In diesem Fall setzen Sie den Server der Gefahr eines Denial-of-Service-Angriffs aus, wenn eine böswillige Nachricht einen extrem langen Wert für diesen Datenmember enthält.For example, if you create a data contract type with a data member property of type integer, and in the set accessor implementation allocate an array based on the property value, you expose the possibility of a denial-of-service attack if a malicious message contains an extremely large value for this data member. Vermeiden Sie in der Regel Zuordnungen, die auf eingehenden Daten oder langwierigen Verarbeitungen im Benutzercode basieren (insbesondere, wenn die langwierige Verarbeitung durch wenige eingehende Daten verursacht werden kann).In general, avoid any allocations based on incoming data or lengthy processing in user-provided code (especially if lengthy processing can be caused by a small amount of incoming data). Berücksichtigen Sie bei der Sicherheitsanalyse von Benutzercode auch alle möglichen Schwachstellen (d. h. alle Codeverzweigungen, an denen Ausnahmen ausgelöst werden).When performing security analysis of user-provided code, make sure to also consider all failure cases (that is, all code branches where exceptions are thrown).

Der Code, der sich innerhalb der Dienstimplementierung für die einzelnen Vorgänge befindet, ist das letzte Beispiel für Benutzercode.The ultimate example of user-provided code is the code inside your service implementation for each operation. Für die Sicherheit Ihrer Dienstimplementierung sind Sie verantwortlich.The security of your service implementation is your responsibility. Es kann leicht passieren, dass versehentlich unsichere Vorgänge implementiert werden, die das Risiko von Denial-of-Service-Angriffen mit sich bringen.It is easy to inadvertently create insecure operation implementations that may result in denial-of-service vulnerabilities. Stellen Sie sich z. B. einen Vorgang vor, der anhand einer Zeichenfolge aus einer Datenbank eine Liste der Kunden zurückgibt, deren Name mit dieser Zeichenfolge beginnt.For example, an operation that takes a string and returns the list of customers from a database whose name starts with that string. Wenn Sie mit großen Datenbanken arbeiten und die übergebene Zeichenfolge besteht nur aus einem einzelnen Buchstaben, ist die Nachricht, die der Code zu erstellen versucht, möglicherweise größer als der verfügbare Arbeitspeicher. Somit schlägt der gesamte Dienst fehl.If you are working with a large database and the string being passed is just a single letter, your code may attempt to create a message larger than all available memory, causing the entire service to fail. (Eine OutOfMemoryException kann in .NET Framework.NET Framework nicht behoben werden und führt immer zum Beenden der Anwendung.)(An OutOfMemoryException is not recoverable in the .NET Framework.NET Framework and always results in the termination of your application.)

Stellen Sie sicher, dass die verschiedenen Erweiterbarkeitspunkte keinen schädlichen Code enthalten.You should ensure that no malicious code is plugged in to the various extensibility points. Dies ist besonders dann relevant, wenn er unter teilweiser Vertrauenswürdigkeit ausgeführt wird, und mit Typen arbeitet, die in nicht voll vertrauenswürdigen Assemblys deklariert sind, oder Komponenten erstellt, die von teilweise vertrauenswürdigem Code verwendet werden.This is especially relevant when running under partial trust, dealing with types from partially-trusted assemblies, or creating components usable by partially-trusted code. Weitere Informationen finden Sie unter "Bedrohungen durch teilweise vertrauenswürdigen Code" in einem späteren Abschnitt.For more information, see "Partial Trust Threats" in a later section.

Beachten Sie, dass bei Ausführung unter teilweiser Vertrauenswürdigkeit die Infrastruktur der Datenvertragsserialisierung nur eine beschränkte Teilmenge des Datenvertragsprogrammiermodells unterstützt – beispielsweise werden private Datenmember oder Typen, die das SerializableAttribute -Attribut verwenden, nicht unterstützt.Note that when running in partial trust, the data contract serialization infrastructure supports only a limited subset of the data contract programming model - for example, private data members or types using the SerializableAttribute attribute are not supported. Weitere Informationen finden Sie unter teilweise Vertrauenswürdigkeit.For more information, see Partial Trust.

Vermeiden einer unbeabsichtigten Offenlegung von InformationenAvoiding Unintentional Information Disclosure

Spielt beim Entwerfen serialisierbarer Typen der Sicherheitsgedanke eine Rolle, ist eine mögliche Offenlegung von Informationen von besonderem Belang.When designing serializable types with security in mind, information disclosure is a possible concern.

Berücksichtigen Sie die folgenden Punkte:Consider the following points:

  • Das Programmiermodell DataContractSerializer lässt das Offenlegen von privaten und internen Daten außerhalb des Typs oder der Assembly während der Serialisierung zu.The DataContractSerializer programming model allows the exposure of private and internal data outside of the type or assembly during serialization. Darüber hinaus kann die Form eines Typs während des Schemaexports offengelegt werden.Additionally, the shape of a type can be exposed during schema export. Stellen Sie sicher, dass Sie das Serialisierungskonzept des Typs verstehen.Be sure to understand your type's serialization projection. Wenn Sie nichts offenlegen möchten, deaktivieren Sie dementsprechend die Serialisierung (z. B. bei einem Datenvertrag, indem Sie das DataMemberAttribute -Attribut nicht anwenden).If you do not want anything exposed, disable serializing it (for example, by not applying the DataMemberAttribute attribute in the case of a data contract).

  • Denken Sie daran, dass derselbe Typ je nach verwendetem Serialisierungsprogramm mehrere Serialisierungskonzepte umfassen kann.Be aware that the same type may have multiple serialization projections, depending on the serializer in use. Ein Typ macht möglicherweise eine Reihe von Daten zugänglich, wenn er mit DataContractSerializer verwendet wird und mit XmlSerializereine andere Reihe von Daten.The same type may expose one set of data when used with the DataContractSerializer and another set of data when used with the XmlSerializer. Wird versehentlich das falsche Serialisierungsprogramm verwendet, könnten Informationen in die falschen Hände gelangen.Accidentally using the wrong serializer may lead to information disclosure.

  • Wenn Sie XmlSerializer im RPC/encoded-Modus des Legacy-Remoteprozeduraufrufs verwenden, legen Sie vielleicht unbeabsichtigt die Form des Objektdiagramms der Absenderseite für die Empfängerseite offen.Using the XmlSerializer in legacy remote procedure call (RPC)/encoded mode may unintentionally expose the shape of the object graph on the sending side to the receiving side.

Verhindern von Denial-of-Service-AngriffenPreventing Denial-of-Service Attacks

KontingenteQuotas

Wenn die Empfängerseite dazu veranlasst wird, eine erhebliche Arbeitsspeichermenge zuzuordnen, kann es sich dabei um einen Denial-of-Service-Angriff handeln.Causing the receiving side to allocate a significant amount of memory is a potential denial-of-service attack. Dieser Abschnitt behandelt zwar vorwiegend Probleme des Arbeitsspeicherverbrauchs, der durch großen Nachrichten verursacht wird, es können jedoch auch andere Angriffe stattfinden.While this section concentrates on memory consumption issues arising from large messages, other attacks may occur. Nachrichten können beispielsweise eine außergewöhnlich lange Verarbeitungsdauer beanspruchen.For example, messages may use a disproportionate amount of processing time.

Denial-of-Service-Angriffe werden häufig mithilfe von Kontingenten abgeschwächt.Denial-of-service attacks are usually mitigated using quotas. Beim Überschreiten eines Kontingents wird in der Regel eine QuotaExceededException -Ausnahme ausgelöst.When a quota is exceeded, a QuotaExceededException exception is normally thrown. Ohne Kontingent kann eine böswillige Nachricht den gesamten verfügbaren Arbeitsspeicher belegen und eine OutOfMemoryException -Ausnahme auslösen, oder es werden alle verfügbaren Stapel verbraucht, was zu einer StackOverflowExceptionführt.Without the quota, a malicious message may cause all available memory to be accessed, resulting in an OutOfMemoryException exception, or all available stacks to be accessed, resulting in a StackOverflowException.

Das Problem eines überschrittenen Kontingents ist behebbar. Wenn dabei ein Dienst aktiv ist, wird die aktuell verarbeitete Nachricht verworfen, der Dienst wird weiterhin ausgeführt und verarbeitet weitere Nachrichten.The quota exceeded scenario is recoverable; if encountered in a running service, the message currently being processed is discarded and the service keeps running and processes further messages. Wenn jedoch kein Arbeitspeicher mehr verfügbar ist oder ein Stapelüberlauf eintritt, kann das Problem in .NET Framework.NET Frameworknicht behoben werden. Der Dienst wird im Fall dieser Ausnahmen beendet.The out-of-memory and stack overflow scenarios, however, are not recoverable anywhere in the .NET Framework.NET Framework; the service terminates if it encounters such exceptions.

Kontingente schließen in WCF beinhalten keine Vorabbelegung.Quotas in WCF do not involve any pre-allocation. Ist beispielsweise das MaxReceivedMessageSize -Kontingent (das für verschiedene Klassen verwendet wir) auf 128 KB festgelegt, heißt das nicht, dass automatisch jeder Nachricht 128 KB zugeordnet werden.For example, if the MaxReceivedMessageSize quota (found on various classes) is set to 128 KB, it does not mean that 128 KB is automatically allocated for each message. Die tatsächliche zugeordnete Menge hängt von der tatsächlichen Größe der eingehenden Nachricht ab.The actual amount allocated depends on the actual incoming message size.

Auf der Transportebene ist eine Vielzahl von Kontingenten verfügbar.Many quotas are available at the transport layer. Dabei handelt es sich um Kontingente, die vom jeweils verwendeten Transportkanal (HTTP, TCP usw.) eingesetzt werden.These are quotas enforced by the specific transport channel in use (HTTP, TCP, and so on). Einige dieser Kontingente werden in diesem Thema erläutert, eine ausführliche Beschreibung finden Sie jedoch unter Transport Quotas.While this topic discusses some of these quotas, these quotas are described in detail in Transport Quotas.

Sicherheitsrisiko bei HashtabellenHashtable Vulnerability

Wenn Datenverträge Hashtabellen oder Auflistungen enthalten, besteht ein Sicherheitsrisiko.A vulnerability exists when data contracts contain hashtables or collections. Das Problem tritt auf, wenn in eine Hashtabelle eine große Anzahl von Werten eingefügt wird und eine große Anzahl dieser Werte den gleichen Hashwert generiert.The problem occurs if a large number of values are inserted into a hashtable where a large number of those values generate the same hash value. Dies kann als DoS-Angriff genutzt werden.This can be used as a DOS attack. Dieses Sicherheitsrisiko lässt sich durch Festlegen des MaxRecievedMessageSize-Bindungskontingents verringern.This vulnerability can be mitigated by setting the MaxRecievedMessageSize binding quota. Wenn dieses Kontingent festgelegt wird, um solche Angriffe zu verhindern, ist Sorgfalt geboten.Care must be taken while setting this quota in order to prevent such attacks. Mit dem Kontingent wird die Größe der WCF-Nachricht begrenzt.This quota puts an upper limit on the size of WCF message. Verwenden Sie außerdem in den Datenverträgen keine Hashtabellen oder Auflistungen.Additionally, avoid using hashtables or collections in your data contracts.

Einschränken des Arbeitsspeicherverbrauch ohne StreamingLimiting Memory Consumption Without Streaming

Das Sicherheitsmodell zu großen Nachrichten hängt davon ab, ob Streaming verwendet wird.The security model around large messages depends on whether streaming is in use. In einem einfachen Fall ohne Streaming werden Nachrichten im Arbeitsspeicher gepuffert.In the basic, non-streamed case, messages are buffered into memory. Verwenden Sie hier zur Abwehr großer Nachrichten das MaxReceivedMessageSize -Kontingent für TransportBindingElement oder für die vom System bereitgestellten Bindungen, und schränken Sie damit die maximal verarbeitete Nachrichtengröße ein.In this case, use the MaxReceivedMessageSize quota on the TransportBindingElement or on the system-provided bindings to protect against large messages by limiting the maximum message size to access. Beachten Sie, dass ein Dienst mehrere Nachrichten gleichzeitig verarbeiten kann, die sich dann alle im Arbeitsspeicher befinden.Note that a service may be processing multiple messages at the same time, in which case they are all in memory. Verwenden Sie die Drosselungsfunktion, um diese Bedrohung zu verringern.Use the throttling feature to mitigate this threat.

Beachten Sie auch, dass MaxReceivedMessageSize keine Obergrenze für den Arbeitsspeicherverbrauch der einzelnen Nachrichten festlegt, sondern den Verbrauch auf eine konstante Größe beschränkt.Also note that MaxReceivedMessageSize does not place an upper bound on per-message memory consumption, but limits it to within a constant factor. Angenommen, MaxReceivedMessageSize ist auf 1&#160;MB festgelegt. Wenn dann eine 1-MB-Nachricht eingeht und anschließend deserialisiert wird, ist weiterer Arbeitsspeicher zur Aufnahme des deserialisierten Objektdiagramms erforderlich. Folglich liegt der insgesamt benötigte Arbeitsspeicher bei gut über 1&#160;MB.For example, if the MaxReceivedMessageSize is 1 MB and a 1-MB message is received and then deserialized, additional memory is required to contain the deserialized object graph, resulting in total memory consumption well over 1 MB. Vermeiden Sie deshalb, serialisierbare Typen zu erstellen, die bei nur wenigen eingehenden Daten einen erheblichen Arbeitsspeicherverbrauch verursachen.For this reason, avoid creating serializable types that could result in significant memory consumption without much incoming data. Z. B. ein Datenvertrag "Meinvertrag" mit 50 optionalen datenmemberfeldern und einer weiteren 100 privaten Feldern werden, mit der XML-Konstruktion instanziiert konnte "<Meinvertrag / >".For example, a data contract "MyContract" with 50 optional data member fields and an additional 100 private fields could be instantiated with the XML construction "<MyContract/>". Bei diesem XML-Konstrukt wird Arbeitsspeicher für 150 Felder belegt.This XML results in memory being accessed for 150 fields. Datenmember sind standardmäßig optional.Note that data members are optional by default. Das Problem wird verschärft, wenn ein solcher Typ Teil eines Arrays ist.The problem is compounded when such a type is part of an array.

MaxReceivedMessageSize allein reicht nicht aus, um alle Denial-of-Service-Angriffe zu verhindern.MaxReceivedMessageSize alone is not enough to prevent all denial-of-service attacks. Das Deserialisierungsprogramm kann z. B. von einer eingehenden Nachricht gezwungen werden, ein tief geschachteltes Objektdiagramm (ein Objekt, das ein anderes Objekt enthält, das wiederum ein Objekt enthält usw.) zu deserialisieren.For example, the deserializer may be forced to deserialize a deeply-nested object graph (an object that contains another object that contains yet another one, and so on) by an incoming message. Sowohl DataContractSerializer als auch XmlSerializer rufen zum Deserialisieren solcher Diagramme Methoden in einer geschachtelte Weise auf.Both the DataContractSerializer and the XmlSerializer call methods in a nested way to deserialize such graphs. Eine tiefe Schachtelung von Methodenaufrufen kann zu einer nicht behebbaren StackOverflowExceptionführen.Deep nesting of method calls may result in an unrecoverable StackOverflowException. Diese Gefahr verringert sich, wenn das MaxDepth -Kontingent die Schachtelungstiefe von XML einschränkt (wie im Abschnitt "Sicheres Verwenden von XML" weiter unten in diesem Thema erläutert wird).This threat is mitigated by setting the MaxDepth quota to limit the level of XML nesting, as discussed in the "Using XML Safely" section later in the topic.

MaxReceivedMessageSize festzulegen, ist bei der Verwendung einer binären XML-Codierung besonders wichtig.Setting additional quotas to MaxReceivedMessageSize is especially important when using binary XML encoding. Die Verwendung einer binären Codierung ähnelt in gewisser Weise einer Komprimierung: eine kleine Gruppe von Bytes in der eingehenden Nachricht kann eine große Menge von Daten darstellen.Using binary encoding is somewhat equivalent to compression: a small group of bytes in the incoming message may represent a lot of data. Deshalb kann selbst eine Nachricht, die im Rahmen des MaxReceivedMessageSize -Limits liegt, in erweiterter Form wesentlich mehr Arbeitsspeicher beanspruchen.Thus, even a message fitting into the MaxReceivedMessageSize limit may take up much more memory in fully expanded form. Um diese speziellen Risiken durch XML zu verringern, müssen alle XML-Readerkontingente richtig festgelegt werden (siehe "Sicheres Verwenden von XML" weiter unten in diesem Thema).To mitigate such XML-specific threats, all of the XML reader quotas must be set correctly, as discussed in the "Using XML Safely" section later in this topic.

Einschränken des Arbeitsspeicherverbrauch mit StreamingLimiting Memory Consumption with Streaming

Beim Streaming verwenden Sie zum Schutz vor Denial-of-Service-Angriffen möglicherweise eine niedrige MaxReceivedMessageSize -Einstellung.When streaming, you may use a small MaxReceivedMessageSize setting to protect against denial-of-service attacks. Mit Streaming sind komplexere Szenarien möglich.However, more complicated scenarios are possible with streaming. Ein Dateiuploaddienst akzeptiert z. B. Dateien, die größer sind als der gesamte verfügbare Arbeitsspeicher.For example, a file upload service accepts files larger than all available memory. Legen Sie in diesem Fall MaxReceivedMessageSize auf einen extrem hohen Wert fest, da voraussichtlich fast keine Daten im Arbeitsspeicher gepuffert werden und die Nachricht per Streaming direkt auf die Festplatte übertragen wird.In this case, set the MaxReceivedMessageSize to an extremely large value, expecting that almost no data is buffered in memory and the message streams directly to disk. Wenn eine böswillige Nachricht aus irgendeinem Grund WCF Daten zu Puffern, statt per streaming in diesem Fall kann MaxReceivedMessageSize keinen Schutz mehr vor einer Nachricht, die den gesamten verfügbaren Arbeitsspeicher.If a malicious message can somehow force WCF to buffer data instead of streaming it in this case, MaxReceivedMessageSize no longer protects against the message accessing all available memory.

Um diese Bedrohung zu mindern, vorhanden bestimmte kontingenteinstellungen auf verschiedenen WCF-Datenverarbeitungskomponenten dieser Grenzwert Pufferung.To mitigate this threat, specific quota settings exist on various WCF data-processing components that limit buffering. Am wichtigsten ist hierbei die MaxBufferSize -Eigenschaft für verschiedene Transportbindungselemente und Standardbindungen.The most important of these is the MaxBufferSize property on various transport binding elements and standard bindings. Berücksichtigen Sie beim Streaming die maximale Arbeitsspeichermenge, die Sie für einzelne Nachrichten zuordnen möchten, wenn Sie dieses Kontingent festlegen.When streaming, this quota should be set taking into account the maximum amount of memory you are willing to allocate per message. Wie bei MaxReceivedMessageSizewird mit dieser Einstellung kein absolutes Maximum für den Arbeitsspeicherverbrauch festgelegt, sondern der Verbrauch wird auf eine konstante Größe beschränkt.As with MaxReceivedMessageSize, the setting does not put an absolute maximum on memory consumption but only limits it to within a constant factor. Denken Sie auch hier wie bei MaxReceivedMessageSizean die Möglichkeit, dass mehrere Nachrichten gleichzeitig verarbeitet werden.Also, as with MaxReceivedMessageSize, be aware of the possibility of multiple messages being processed simultaneously.

Näheres zu MaxBufferSizeMaxBufferSize Details

Die MaxBufferSize Eigenschaft beschränkt Massenkopieren Pufferung WCF ist.The MaxBufferSize property limits any bulk buffering WCF does. Beispielsweise führt eine Puffer WCF immer SOAP-Header und SOAP-Fehler sowie eventuelle MIME-Teile in der gewohnten Lesefolge in einer Nachricht Message Transmission Optimization Mechanism (MTOM) nicht gefunden.For example, WCF always buffers SOAP headers and SOAP faults, as well as any MIME parts found to be not in the natural reading order in an Message Transmission Optimization Mechanism (MTOM) message. Diese Einstellung schränkt die Menge der gepufferten Daten in all diesen Fällen ein.This setting limits the amount of buffering in all these cases.

WCF erreicht dies durch Übergeben der MaxBufferSize Wert an die verschiedenen Komponenten, die möglicherweise eine Pufferung.WCF accomplishes this by passing the MaxBufferSize value to the various components that may buffer. Beispielsweise akzeptieren einige CreateMessage -Überladungen der Message -Klasse den maxSizeOfHeaders -Parameter.For example, some CreateMessage overloads of the Message class take a maxSizeOfHeaders parameter. WCF übergibt die MaxBufferSize -Wert an diesen Parameter zur Begrenzung des Umfangs der SOAP-headerpufferung.WCF passes the MaxBufferSize value to this parameter to limit the amount of SOAP header buffering. Bei einer direkten Verwendung der Message -Klasse ist es wichtig, diesen Parameter festzulegen.It is important to set this parameter when using the Message class directly. Im Allgemeinen ist beim Verwenden einer Komponente in WCF, das Kontingent Parameter akzeptiert, es wichtig zu verstehen von Auswirkungen auf die Sicherheit, Parameter und korrekt festgelegt sind.In general, when using a component in WCF that takes quota parameters, it is important to understand the security implications of these parameters and set them correctly.

Auch der MTOM-Nachrichtenencoder verfügt über eine MaxBufferSize -Einstellung.The MTOM message encoder also has a MaxBufferSize setting. Bei der Verwendung von Standardbindungen wird hierfür automatisch der MaxBufferSize -Wert der Transportebene festgelegt.When using standard bindings, this is set automatically to the transport-level MaxBufferSize value. Wenn jedoch mit dem Bindungselement des MTOM-Nachrichtenencoders eine benutzerdefinierte Bindung erstellt wird, ist es wichtig, die MaxBufferSize -Eigenschaft beim Verwenden von Streaming auf einen sicheren Wert festzulegen.However, when using the MTOM message encoder binding element to construct a custom binding, it is important to set the MaxBufferSize property to a safe value when streaming is used.

XML-basierte StreamingangriffeXML-Based Streaming Attacks

MaxBufferSize allein reicht nicht aus, stellen Sie sicher, dass WCF nicht zur Pufferung bei einem streaming erwarteten erzwungen werden kann.MaxBufferSize alone is not enough to ensure that WCF cannot be forced into buffering when streaming is expected. Der WCF-XML-Readers gepuffert z. B. immer das gesamte Starttag des XML-Element beim Lesen eines neuen Elements beginnen.For example, the WCF XML readers always buffer the entire XML element start tag when starting to read a new element. Das dient der ordnungsgemäßen Verarbeitung von Namespaces und Attributen.This is done so that namespaces and attributes are properly processed. Wenn MaxReceivedMessageSize hoch konfiguriert wird (z. B. um eine umfangreiches Streaming direkt auf die Festplatte zu ermöglichen), könnte eine böswillige Nachricht erstellt werden, in der der gesamte Nachrichtentext aus einem großen Starttag für XML-Elemente besteht.If MaxReceivedMessageSize is configured to be large (for example, to enable a direct-to-disk large file streaming scenario), a malicious message may be constructed where the entire message body is a large XML element start tag. Der Versuch, dieses Starttag zu lesen, führt zu einer OutOfMemoryException.An attempt to read it results in an OutOfMemoryException. Dies ist eine der vielen möglichen XML-basierte Denial-of-Service-Angriffen, die alle gemindert werden können, mithilfe von XML-readerkontingenten, der im Abschnitt "Sicheres Verwenden von XML" weiter unten in diesem Thema erläutert.This is one of many possible XML-based denial-of-service attacks that can all be mitigated using XML reader quotas, discussed in the "Using XML Safely" section later in this topic. Beim Streaming ist es besonders wichtig, alle diese Kontingente festzulegen.When streaming, it is especially important to set all of these quotas.

Kombinieren von Streaming- und PufferprogrammiermodellenMixing Streaming and Buffering Programming Models

Viele mögliche Angriffe ergeben sich aus kombinierten Streaming- und anderen Programmiermodellen im gleichen Dienst.Many possible attacks arise from mixing streaming and non-streaming programming models in the same service. Angenommen, ein Dienst umfasst zwei Vorgänge: ein Vorgang verwendet einen Stream und ein anderer ein Array eines benutzerdefinierten Typs.Suppose there is a service contract with two operations: one takes a Stream and another takes an array of some custom type. MaxReceivedMessageSize wird außerdem auf einen großen Wert festgelegt, damit der erste Vorgang große Streams verarbeiten kann.Suppose also that MaxReceivedMessageSize is set to a large value to enable the first operation to process large streams. Leider bedeutet das, dass große Nachrichten nun auch an den zweiten Vorgang gesendet werden können und dass das Deserialisierungsprogramm Daten als Array im Arbeitsspeicher puffert, bevor der Vorgang aufgerufen wird.Unfortunately, this means that large messages can now be sent to the second operation as well, and the deserializer buffers data in memory as an array before the operation is called. Das stellt einen potenzieller Denial-of-Service-Angriff dar: das MaxBufferSize -Kontingent schränkt die Größe des Nachrichtentextes, womit das Deserialisierungsprogramm arbeitet, nicht ein.This is a potential denial-of-service attack: the MaxBufferSize quota does not limit the size of the message body, which is what the deserializer works with.

Vermeiden Sie es deshalb, auf Streams basierende Vorgänge mit anderen Vorgängen im selben Vertrag zu kombinieren.For this reason, avoid mixing stream-based and non-streamed operations in the same contract. Sollte eine Kombination der beiden Programmiermodelle zwingend erforderlich sein, treffen Sie die folgenden Vorkehrungen:If you absolutely must mix the two programming models, use the following precautions:

  • Deaktivieren Sie die IExtensibleDataObject -Funktion, indem Sie die IgnoreExtensionDataObject -Eigenschaft von ServiceBehaviorAttribute auf truefestlegen.Turn off the IExtensibleDataObject feature by setting the IgnoreExtensionDataObject property of the ServiceBehaviorAttribute to true. Dadurch stellen Sie sicher, dass nur Member deserialisiert werden, die zum Vertrag gehören.This ensures that only members that are a part of the contract are deserialized.

  • Legen Sie die MaxItemsInObjectGraph -Eigenschaft von DataContractSerializer auf einen sicheren Wert fest.Set the MaxItemsInObjectGraph property of the DataContractSerializer to a safe value. Dieses Kontingent ist auch für das ServiceBehaviorAttribute -Attribut oder die Konfiguration verfügbar.This quota is also available on the ServiceBehaviorAttribute attribute or through configuration. Mit diesem Kontingent wird Anzahl der Objekte eingeschränkt, die in einer Deserialisierungsfolge deserialisiert werden.This quota limits the number of objects that are deserialized in one deserialization episode. In der Regel wird jeder Vorgangsparameter oder jeder Nachrichtentextteil in einem Nachrichtenvertrag in einer Folge deserialisiert.Normally, each operation parameter or message body part in a message contract is deserialized in one episode. Beim Deserialisieren von Arrays wird jeder Arrayeintrag als separates Objekt betrachtet.When deserializing arrays, each array entry is counted as a separate object.

  • Legen Sie alle XML-Readerkontingente auf sichere Werte fest.Set all of the XML reader quotas to safe values. Achten Sie auf MaxDepth, MaxStringContentLengthund MaxArrayLength , und vermeiden Sie Zeichenfolgen in anderen als Streamingvorgängen.Pay attention to MaxDepth, MaxStringContentLength, and MaxArrayLength and avoid strings in non-streaming operations.

  • Überprüfen Sie die Liste der bekannten Typen und denken Sie daran, dass jeder davon jederzeit instanziiert werden kann (siehe "Verhindern des Ladens unbeabsichtigter Typen" weiter unten in diesem Thema).Review the list of known types, keeping in mind that any one of them can be instantiated at any time (see the "Preventing Unintended Types from Being Loaded" section later in this topic).

  • Verwenden Sie keine Typen, die die IXmlSerializable -Schnittstelle implementieren und eine große Datenmenge puffern.Do not use any types that implement the IXmlSerializable interface that buffer a lot of data. Fügen Sie keine Typen dieser Art der Liste der bekannten Typen hinzu.Do not add such types to the list of known types.

  • Verwenden Sie kein XmlElementund keine XmlNode -Arrays, Byte -Arrays oder Typen, die ISerializable in einem Vertrag implementieren.Do not use the XmlElement, XmlNode arrays, Byte arrays, or types that implement ISerializable in a contract.

  • Verwenden Sie kein XmlElementund keine XmlNode -Arrays, Byte -Arrays oder Typen, die ISerializable in der Liste der bekannten Typen implementieren.Do not use the XmlElement, XmlNode arrays, Byte arrays, or types that implement ISerializable in the list of known types.

Die vorangehenden Vorkehrungen sind relevant, wenn der Vorgang ohne Streaming DataContractSerializerverwendet.The preceding precautions apply when the non-streamed operation uses the DataContractSerializer. Kombinieren Sie niemals Streaming- und andere Programmiermodelle im selben Dienst, wenn Sie XmlSerializerverwenden, denn der Schutz von MaxItemsInObjectGraph -Kontingenten ist dabei nicht vorhanden.Never mix streaming and non-streaming programming models on the same service if you are using the XmlSerializer, because it does not have the protection of the MaxItemsInObjectGraph quota.

Angriffe durch langsame StreamsSlow Stream Attacks

Eine Kategorie von Denial-of-Service-Angriffen beim Streaming wirkt sich nicht auf den Arbeitsspeicherverbrauch aus.A class of streaming denial-of-service attacks does not involve memory consumption. Stattdessen konzentriert sich der Angriff auf das langsame Senden oder Empfangen von Daten.Instead, the attack involves a slow sender or receiver of data. Während auf das Senden oder Empfang der Daten gewartet wird, erschöpfen sich die Ressourcen wie Threads und die verfügbaren Verbindungen.While waiting for the data to be sent or received, resources such as threads and available connections are exhausted. Dieser Fall kann als Ergebnis eines böswilligen Angriffs oder durch einen legitimen Absender/Empfänger bei einer langsamen Netzwerkverbindung entstehen.This situation could arise either as a result of a malicious attack or from a legitimate sender/receiver on a slow network connection.

Legen Sie die Transporttimeouts richtig fest, um diese Angriffe zu verhindern.To mitigate these attacks, set the transport time-outs correctly. Weitere Informationen finden Sie unter Transportkontingente.For more information, see Transport Quotas. Verwenden Sie außerdem niemals synchrone Read oder Write Operationen beim Arbeiten mit Datenströmen in WCF.Secondly, never use synchronous Read or Write operations when working with streams in WCF.

Sicheres Verwenden von XMLUsing XML Safely

Hinweis

Obwohl dieser Abschnitt XML behandelt, gelten die Informationen auch für JSON-Dokumente (JavaScript Objekt Notation).Although this section is about XML, the information also applies to JavaScript Object Notation (JSON) documents. Die Kontingente funktionieren auf ähnliche Weise und verwenden Mapping Between JSON and XML.The quotas work similarly, using Mapping Between JSON and XML.

Sichere XML-ReaderSecure XML Readers

Das XML-Infoset bildet die Grundlage für die Verarbeitung von Nachrichten in WCF.The XML Infoset forms the basis of all message processing in WCF. Das Akzeptieren von XML-Daten aus einer nicht vertrauenswürdigen Quelle ermöglicht eine Reihe von Denial-of-Service-Angriffen, die verhindert werden müssen.When accepting XML data from an untrusted source, a number of denial-of-service attack possibilities exist that must be mitigated. WCF bietet spezielle, sichere XML-Reader.WCF provides special, secure XML readers. Diese Reader werden automatisch erstellt, bei Verwendung einer standardcodierung in WCF (Text, Binär oder MTOM).These readers are created automatically when using one of the standard encodings in WCF (text, binary, or MTOM).

Einige der Sicherheitsfunktionen dieser Reader sind immer aktiv.Some of the security features on these readers are always active. Die Reader verarbeiten z. B. keine Dokumenttypdefinitionen (DTDs), die eine mögliche Quelle von Denial-of-Service-Angriffen darstellen und niemals in rechtmäßigen SOAP-Nachrichten auftreten sollten.For example, the readers never process document type definitions (DTDs), which are a potential source of denial-of-service attacks and should never appear in legitimate SOAP messages. Zu weiteren Sicherheitsfunktionen gehören Readerkontingente, die konfiguriert werden müssen. Im folgenden Abschnitt werden diese Kontingente beschrieben.Other security features include reader quotas that must be configured, which are described in the following section.

Wenn Sie direkt mit XML-Readern arbeiten (z. B. beim Schreiben von eigenen benutzerdefinierten Encoders oder beim direkten arbeiten die Message Klasse), verwenden Sie stets die sicheren Reader WCF auf, wenn es besteht die Möglichkeit der Arbeit mit nicht vertrauenswürdigen Daten.When working directly with XML readers (such as when writing your own custom encoder or when working directly with the Message class), always use the WCF secure readers when there is a chance of working with untrusted data. Erstellen Sie die sicheren Reader, indem Sie eine der Überladungen der statischen Factorymethode von CreateTextReader, CreateBinaryReaderoder CreateMtomReader für die XmlDictionaryReader -Klasse aufrufen.Create the secure readers by calling one of the static factory method overloads of CreateTextReader, CreateBinaryReader, or CreateMtomReader on the XmlDictionaryReader class. Geben Sie beim Erstellen eines Readers sichere Kontingentwerte an.When creating a reader, pass in secure quota values. Rufen Sie nicht die Überladungen der Create -Methode auf.Do not call the Create method overloads. Dazu erstellen Sie einen WCF-Reader nicht.These do not create a WCF reader. Stattdessen wird ein Reader erstellt, der nicht durch die in diesem Abschnitt beschriebenen Sicherheitsfunktionen geschützt ist.Instead, a reader is created that is not protected by the security features described in this section.

ReaderkontingenteReader Quotas

Die sicheren XML-Reader verfügen über fünf konfigurierbare Kontingente.The secure XML readers have five configurable quotas. Diese werden in der Regel mithilfe der ReaderQuotas -Eigenschaft für das Codierungsbindungselement oder die Standardbindungen konfiguriert oder mithilfe eines XmlDictionaryReaderQuotas -Objekts, das beim Erstellen eines Readers übergeben wird.These are normally configured using the ReaderQuotas property on the encoding binding elements or standard bindings, or by using an XmlDictionaryReaderQuotas object passed when creating a reader.

MaxBytesPerReadMaxBytesPerRead

Dieses Kontingent beschränkt die Anzahl der Bytes, die in einem einzelnen Read -Vorgang beim Lesen des Starttags des Elements und seiner Attribute gelesen werden können.This quota limits the number of bytes that are read in a single Read operation when reading the element start tag and its attributes. (In Fällen ohne Streaming wird der Elementname selbst nicht in die Berechnung des Kontingents einbezogen.) MaxBytesPerRead ist aus den folgenden Gründen wichtig:(In non-streamed cases, the element name itself is not counted against the quota.) MaxBytesPerRead is important for the following reasons:

  • Der Elementname und dessen Attribute werden immer im Arbeitsspeicher gepuffert, wenn sie gelesen werden.The element name and its attributes are always buffered in memory when they are being read. Deshalb ist es wichtig, dass dieses Kontingent im Streamingmodus richtig festgelegt wird, um bei einem erwarteten Streaming eine übermäßige Pufferung zu vermeiden.Therefore, it is important to set this quota correctly in streaming mode to prevent excessive buffering when streaming is expected. Informationen zum tatsächlichen Pufferumfang finden Sie unten in den Ausführungen zum MaxDepth -Kontingent.See the MaxDepth quota section for information about the actual amount of buffering that takes place.

  • Bei zu vielen XML-Attributen kann die Verarbeitungszeit übermäßig lange dauern, da die Attributnamen auf Eindeutigkeit überprüft werden müssen.Having too many XML attributes may use up disproportionate processing time because attribute names have to be checked for uniqueness. MaxBytesPerRead mindert dieses Risiko.MaxBytesPerRead mitigates this threat.

MaxDepthMaxDepth

Diese Kontingent schränkt die maximale Schachtelungstiefe von XML-Elementen ein.This quota limits the maximum nesting depth of XML elements. Angenommen, das Dokument "<ein ><B ><C / ></b > < /a >" hat eine Schachtelungstiefe von drei Elementen.For example, the document "<A><B><C/></B></A>" has a nesting depth of three. MaxDepth ist aus den folgenden Gründen wichtig:MaxDepth is important for the following reasons:

  • MaxDepth interagiert mit MaxBytesPerRead: Der Reader behält stets Daten für das aktuelle Element und alle seiner übergeordneten Elemente im Arbeitsspeicher, weshalb der maximale Arbeitsspeicherverbrauch proportional zum Produkt aus diesen beiden Einstellungen ist.MaxDepth interacts with MaxBytesPerRead: the reader always keeps data in memory for the current element and all of its ancestors, so the maximum memory consumption of the reader is proportional to the product of these two settings.

  • Wenn Sie ein tief geschachteltes Objektdiagramm deserialisieren, ist das Deserialisierungsprogramm gezwungen, auf den gesamten Stapel zuzugreifen und eine nicht behebbare StackOverflowExceptionauszulösen.When deserializing a deeply-nested object graph, the deserializer is forced to access the entire stack and throw an unrecoverable StackOverflowException. Ein direkter Zusammenhang besteht zwischen der XML-Schachtelung und der Objektschachtelung sowohl für DataContractSerializer als auch für XmlSerializer.A direct correlation exists between XML nesting and object nesting for both the DataContractSerializer and the XmlSerializer. Verwenden Sie MaxDepth , um diese Bedrohung zu verringern.Use MaxDepth to mitigate this threat.

MaxNameTableCharCountMaxNameTableCharCount

Dieses Kontingent schränkt die Größe der Nametabledes Readers ein.This quota limits the size of the reader’s nametable. Die Nametable enthält bestimmte Zeichenfolgen (z. B. Namespaces and Präfixe), die beim Verarbeiten von XML-Dokumenten auftreten.The nametable contains certain strings (such as namespaces and prefixes) that are encountered when processing an XML document. Diese Zeichenfolgen werden im Arbeitsspeicher gepuffert. Legen Sie deshalb dieses Kontingent fest, um eine übermäßige Pufferung bei einem erwarteten Streaming zu verhindern.As these strings are buffered in memory, set this quota to prevent excessive buffering when streaming is expected.

MaxStringContentLengthMaxStringContentLength

Dieses Kontingent schränkt die maximale Größe der Zeichenfolgen ein, die vom XML-Reader zurückgegeben werden.This quota limits the maximum string size that the XML reader returns. Der Arbeitsspeicherverbrauch im XML-Reader selbst wird mit diesem Kontingent nicht eingeschränkt, jedoch in der Komponente, die den Reader verwendet.This quota does not limit memory consumption in the XML reader itself, but in the component that is using the reader. Wenn DataContractSerializer z.&#160;B. einen Reader verwendet, der mit MaxStringContentLengthgesichert ist, werden keine Zeichenfolgen deserialisiert, deren Größe dieses Kontingent überschreitet.For example, when the DataContractSerializer uses a reader secured with MaxStringContentLength, it does not deserialize strings larger than this quota. Wird die XmlDictionaryReader -Klasse direkt verwendet, beachten nicht alle Methoden dieses Kontingent, sondern nur die Methoden, die speziell für das Lesen dieser Zeichenfolgen entworfen wurden, z.&#160;B. die ReadContentAsString -Methode.When using the XmlDictionaryReader class directly, not all methods respect this quota, but only the methods that are specifically designed to read strings, such as the ReadContentAsString method. Die Value -Eigenschaft für den Reader wird von diesem Kontingent nicht beeinflusst. Sie sollte deshalb nicht verwendet werden, wenn der Schutz benötigt wird, den dieses Kontingent bietet.The Value property on the reader is not affected by this quota, and thus should not be used when the protection this quota provides is necessary.

MaxArrayLengthMaxArrayLength

Dieses Kontingent schränkt die maximale Größe eines Arrays von Primitiven ein, einschließlich Bytearrays, die vom XML-Reader zurückgegeben werden.This quota limits the maximum size of an array of primitives that the XML reader returns, including byte arrays. Der Arbeitsspeicherverbrauch im XML-Reader selbst wird mit diesem Kontingent nicht eingeschränkt, jedoch in der Komponente, die den Reader verwendet.This quota does not limit memory consumption in the XML reader itself, but in whatever component that is using the reader. Wenn DataContractSerializer z.&#160;B. einen Reader verwendet, der mit MaxArrayLengthgesichert ist, werden keine Bytearrays deserialisiert, deren Größe dieses Kontingent überschreitet.For example, when the DataContractSerializer uses a reader secured with MaxArrayLength, it does not deserialize byte arrays larger than this quota. Sollen Streaming- und Pufferprogrammiermodelle in einem einzelnen Vertrag kombiniert werden, ist es wichtig, dieses Kontingent festzulegen.It is important to set this quota when attempting to mix streaming and buffered programming models in a single contract. Denken Sie daran, dass bei einer direkten Verwendung der XmlDictionaryReader -Klasse nur die Methoden dieses Kontingent beachten, die speziell zum Lesen von Arrays beliebiger Größe von bestimmten primitiven Typen entworfen wurden, wie z.&#160;B. ReadInt32Array.Keep in mind that when using the XmlDictionaryReader class directly, only the methods that are specifically designed to read arrays of arbitrary size of certain primitive types, such as ReadInt32Array, respect this quota.

Spezielle Bedrohungen bei der binären CodierungThreats Specific to the Binary Encoding

Binary XML-Codierung unterstützt das WCF umfasst eine wörterbuchzeichenfolgen Funktion.The binary XML encoding WCF supports includes a dictionary strings feature. Eine große Zeichenfolge kann mit wenigen Bytes codiert werden.A large string may be encoded using only a few bytes. Das ermöglicht eine erhebliche Leistungsverbesserung, bringt jedoch neue Angriffsflächen für Denial-of-Service-Bedrohungen mit sich, die abgewehrt werden müssen.This enables significant performance gains, but introduces new denial-of-service threats that must be mitigated.

Es gibt zwei Arten von Wörterbüchern: statisch und dynamisch.There are two kinds of dictionaries: static and dynamic. Das statische Wörterbuch besteht aus eine integrierten Liste langer Zeichenfolgen, die mithilfe eines kurzen Codes in der binären Codierung dargestellt werden können.The static dictionary is a built-in list of long strings that may be represented using a short code in the binary encoding. Diese Zeichenfolgenliste steht beim Erstellen des Readers fest und kann nicht geändert werden.This list of strings is fixed when the reader is created and cannot be modified. Keine der Zeichenfolgen des statischen Standardwörterbuchs, die WCF standardmäßig verwendet sind ausreichend groß ist, um eine ernste Denial-of-Service-Bedrohung darstellen, obwohl sie weiterhin in einem Angriff verwendet werden können.None of the strings in the static dictionary that WCF uses by default are sufficiently large to pose a serious denial-of-service threat, although they may still be used in a dictionary expansion attack. Seien Sie in komplexen Szenarien, in denen Sie ein eigenes statisches Wörterbuch bereitstellen, mit dem Einbringen langer Wörterbuchzeichenfolgen vorsichtig.In advanced scenarios where you supply your own static dictionary, be careful when introducing large dictionary strings.

Die Funktion dynamischer Wörterbücher ermöglicht es Nachrichten, eigene Zeichenfolgen zu definieren und kurzen Codes zuzuordnen.The dynamic dictionaries feature allows messages to define their own strings and associate them with short codes. Diese Zeichenfolgen-Code-Zuordnungen bleiben während der gesamten Kommunikationssitzung im Arbeitsspeicher. Auf diese Weise müssen anschließende Nachrichten die Zeichenfolgen nicht erneut senden und können bereits definierte Codes nutzen.These string-to-code mappings are kept in memory during the entire communication session, such that subsequent messages do not have to resend the strings and can utilize codes that are already defined. Die Länge dieser Zeichenfolgen ist beliebig, weshalb sie eine ernstere Bedrohung darstellen als die Zeichenfolgen im statischen Wörterbuch.These strings may be of arbitrary length and thus pose a more serious threat than those in the static dictionary.

Die erste Bedrohung, die es zu verringern gilt, ist die Möglichkeit eines zu großen dynamischen Wörterbuchs (die Zeichenfolgen-Code-Zuordnung).The first threat that must be mitigated is the possibility of the dynamic dictionary (the string-to-code mapping table) becoming too large. Dieses Wörterbuch kann im Verlauf mehrerer Nachrichten anwachsen. Das MaxReceivedMessageSize -Kontingent bietet somit keinen Schutz, da es sich gesondert auf die einzelnen Nachrichten bezieht.This dictionary may be expanded over the course of several messages, and so the MaxReceivedMessageSize quota offers no protection because it applies only to each message separately. Deshalb gibt es eine gesonderte MaxSessionSize -Eigenschaft für BinaryMessageEncodingBindingElement , die die Größe des Wörterbuchs einschränkt.Therefore, a separate MaxSessionSize property exists on the BinaryMessageEncodingBindingElement that limits the size of the dictionary.

Im Gegensatz zu den meisten anderen Kontingenten wird dieses Kontingent auch beim Schreiben von Nachrichten angewendet.Unlike most other quotas, this quota also applies when writing messages. Wird es beim Lesen einer Nachricht überschritten, wird wie üblich die QuotaExceededException ausgelöst.If it is exceeded when reading a message, the QuotaExceededException is thrown as usual. Wenn es beim Schreiben einer Nachricht überschritten wird, werden alle Zeichenfolgen, die das Überschreiten des Kontingents verursachen, ohne Einbeziehung der Funktion für dynamische Wörterbücher so geschrieben, wie sie sind.If it is exceeded when writing a message, any strings that cause the quota to be exceeded are written as-is, without using the dynamic dictionaries feature.

Bedrohungen durch WörterbucherweiterungenDictionary Expansion Threats

Wörterbucherweiterungen stellen eine wichtige Kategorie von Angriffen binärer Natur dar.A significant class of binary-specific attacks arises from dictionary expansion. Eine kleine Nachricht in binärer Form kann sich in vollständig erweiterter Textform in eine extrem große Nachricht verwandeln, wenn die Wörterbuchzeichenfolgenfunktion umfassend angewendet wird.A small message in binary form may turn into a very large message in fully expanded textual form if it makes extensive use of the string dictionaries feature. Der Erweiterungsfaktor für Zeichenfolgen des dynamischen Wörterbuchs wird durch das MaxSessionSize -Kontingent eingeschränkt, da keine Zeichenfolge des Wörterbuchs die maximale Größe des gesamten dynamischen Wörterbuchs überschreitet.The expansion factor for dynamic dictionary strings is limited by the MaxSessionSize quota, because no dynamic dictionary string exceeds the maximum size of the entire dictionary.

Die Eigenschaften MaxNameTableCharCount, MaxStringContentLengthund MaxArrayLength schränken nur den Arbeitsspeicherverbrauch ein.The MaxNameTableCharCount, MaxStringContentLength, and MaxArrayLength properties only limit memory consumption. In der Regel sind sie zur Abwehr von Bedrohungen in Szenarien ohne Streaming nicht erforderlich, da der Arbeitsspeicherverbrauch bereits durch MaxReceivedMessageSizeeingeschränkt wird.They are normally not required to mitigate any threats in the non-streamed usage because memory usage is already limited by MaxReceivedMessageSize. MaxReceivedMessageSize berechnet jedoch die Bytes vor der Erweiterung.However, MaxReceivedMessageSize counts pre-expansion bytes. Bei der Verwendung der binären Codierung könnte der Arbeitsspeicherverbrauch MaxReceivedMessageSizeüberschreiten und würde lediglich durch den Faktor von MaxSessionSizeeingeschränkt werden.When binary encoding is in use, memory consumption could potentially go beyond MaxReceivedMessageSize, limited only by a factor of MaxSessionSize. Aus diesem Grund ist es wichtig, stets alle Kontingente des Readers festzulegen (insbesondere MaxStringContentLength), wenn die binäre Codierung verwendet wird.For this reason, it is important to always set all of the reader quotas (especially MaxStringContentLength) when using the binary encoding.

Wird die binäre Codierung in Verbindung mit DataContractSerializerverwendet, kann die IExtensibleDataObject -Schnittstelle für einen Angriff durch eine Erweiterung des Wörterbuchs missbraucht werden.When using binary encoding together with the DataContractSerializer, the IExtensibleDataObject interface can be misused to mount a dictionary expansion attack. Diese Schnittstelle stellt im Wesentlichen unbegrenzten Speicher für beliebige Daten bereit, die nicht zum Vertrag gehören.This interface essentially provides unlimited storage for arbitrary data that is not a part of the contract. Wenn Kontingente nicht so niedrig festgelegt werden können, dass MaxSessionSize multipliziert mit MaxReceivedMessageSize kein Problem darstellt, deaktivieren Sie die IExtensibleDataObject -Funktion bei der Verwendung der binären Codierung.If quotas cannot be set low enough such that MaxSessionSize multiplied by MaxReceivedMessageSize does not pose a problem, disable the IExtensibleDataObject feature when using the binary encoding. Legen Sie die IgnoreExtensionDataObject -Eigenschaft für das true -Attribute auf ServiceBehaviorAttribute fest.Set the IgnoreExtensionDataObject property to true on the ServiceBehaviorAttribute attribute. Als Alternative können Sie auch darauf verzichten, die IExtensibleDataObject -Schnittstelle zu implementieren.Alternatively, do not implement the IExtensibleDataObject interface. Weitere Informationen finden Sie unter Aufwärtskompatible Datenverträge.For more information, see Forward-Compatible Data Contracts.

Zusammenfassung der KontingenteQuotas Summary

In der folgenden Tabelle werden die Hinweise zu den Kontingenten zusammengefasst.The following table summarizes the guidance about quotas.

BedingungCondition Wichtige KontingenteImportant quotas to set
Kein Streaming oder Streaming von kleinen Nachrichten, Text oder MTOM-CodierungNo streaming or streaming small messages, text, or MTOM encoding MaxReceivedMessageSize, MaxBytesPerReadund MaxDepthMaxReceivedMessageSize, MaxBytesPerRead, and MaxDepth
Kein Streaming oder Streaming von kleinen Nachrichten und binäre CodierungNo streaming or streaming small messages, binary encoding MaxReceivedMessageSize, MaxSessionSizeund alle ReaderQuotasMaxReceivedMessageSize, MaxSessionSize, and all ReaderQuotas
Streaming von großen Nachrichten, Text oder MTOM-CodierungStreaming large messages, text, or MTOM encoding MaxBufferSize und alle ReaderQuotasMaxBufferSize and all ReaderQuotas
Streaming von großen Nachrichten und binäre CodierungStreaming large messages, binary encoding MaxBufferSize, MaxSessionSizeund alle ReaderQuotasMaxBufferSize, MaxSessionSize, and all ReaderQuotas
  • Timeouts auf Transportebene müssen immer festgelegt werden, und beim Streaming dürfen niemals synchrone Lese-/Schreibvorgänge verwendet werden, unabhängig davon, ob große oder kleine Nachrichten übertragen werden.Transport-level time-outs must always be set and never use synchronous reads/writes when streaming is in use, regardless of whether you are streaming large or small messages.

  • Wenn Sie sich über ein Kontingent nicht klar sind, legen Sie besser einen sicheren Wert fest, statt gar keinen.When in doubt about a quota, set it to a safe value rather than leaving it open.

Verhindern der Ausführung von schädlichem CodePreventing Malicious Code Execution

Bei den folgenden allgemeinen Bedrohungskategorien kann Code ausführt werden und ein unerwünschtes Ergebnis eintreten:The following general classes of threats can execute code and have unintended effects:

  • Das Deserialisierungsprogramm lädt einen schädlichen, unsicheren oder sicherheitsrelevanten Typ.The deserializer loads a malicious, unsafe, or security-sensitive type.

  • Eine eingehende Nachricht veranlasst das Deserialisierungsprogramm, eine Instanz eines normalerweise sicheren Typs so zu erstellen, dass er unerwünschte Folgen hat.An incoming message causes the deserializer to construct an instance of a normally safe type in such a way that it has unintended consequences.

In den folgenden Abschnitten werden diese Bedrohungskategorien näher erläutert.The following sections discuss these classes of threats further.

DataContractSerializerDataContractSerializer

(Sicherheitsinformationen zu XmlSerializer finden Sie in der entsprechenden Dokumentation.) Das Sicherheitsmodell für XmlSerializer ähnelt dem von DataContractSerializer, unterscheidet sich jedoch vorwiegend in den Details.(For security information on the XmlSerializer, see the relevant documentation.) The security model for the XmlSerializer is similar to that of the DataContractSerializer, and differs mostly in details. Beispielsweise wird das XmlIncludeAttribute -Attribut für die Inklusion von Typen verwendet statt des KnownTypeAttribute -Attributs.For example, the XmlIncludeAttribute attribute is used for type inclusion instead of the KnownTypeAttribute attribute. Einige Bedrohungen, die sich speziell auf XmlSerializer beziehen, werden jedoch weiter unten in diesem Thema erläutert.However, some threats unique to the XmlSerializer are discussed later in this topic.

Verhindern des Ladens unerwünschter TypenPreventing Unintended Types from Being Loaded

Das Laden unerwünschter Typen kann schwerwiegende Folgen haben, unabhängig davon, ob der Typ schädlich ist oder nur sicherheitsrelevante Nebeneffekte aufweist.Loading unintended types may have significant consequences, whether the type is malicious or just has security-sensitive side effects. Ein Typ kann Sicherheitslücken verursachen, sicherheitsrelevante Aktionen in seinem Konstruktor oder dem Klassenkonstruktor ausführen, eine große Menge Arbeitsspeicher belegen, was Denial-of-Service-Angriffe vereinfacht, oder nicht behebbare Ausnahmen auslösen.A type may contain exploitable security vulnerability, perform security-sensitive actions in its constructor or class constructor, have a large memory footprint that facilitates denial-of-service attacks, or may throw non-recoverable exceptions. Typen können Klassenkonstruktoren besitzen, die beim Laden des Typs vor dem Erstellen von Instanzen sofort ausgeführt werden.Types may have class constructors that run as soon as the type is loaded and before any instances are created. Aus diesen Gründen ist es wichtig, die Reihe der Typen zu steuern, die das Deserialisierungsprogramm laden kann.For these reasons, it is important to control the set of types that the deserializer may load.

DataContractSerializer führt die Desialisierung mit einer losen Verknüpfung durch.The DataContractSerializer deserializes in a loosely coupled way. Es werden keine Namen von CRL-Typen (Common Language Runtime) oder von Assemblys in den eingehenden Daten gelesen.It never reads common language runtime (CLR) type and assembly names from the incoming data. Das ist mit dem Verhalten von XmlSerializervergleichbar, unterscheidet sich jedoch vom Verhalten von NetDataContractSerializer, BinaryFormatterund von SoapFormatter.This is similar to the behavior of the XmlSerializer, but differs from the behavior of the NetDataContractSerializer, BinaryFormatter, and the SoapFormatter. Die lose Verknüpfung bietet eine gewisse Sicherheit, da Remoteangreifer das Laden eines beliebigen Typs nicht veranlassen können, indem sie diesen Typ einfach in der Nachricht benennen.Loose coupling introduces a degree of safety, because the remote attacker cannot indicate an arbitrary type to load just by naming that type in the message.

DataContractSerializer darf stets einen Typ laden, der in Übereinstimmung mit dem Vertrag gerade erwartet wird.The DataContractSerializer is always allowed to load a type that is currently expected according to the contract. Wenn z. B. ein Datenvertrag einen Datenmember vom Typ Customerenthält, darf DataContractSerializer den Customer -Typ beim Deserialisieren dieses Datenmembers laden.For example, if a data contract has a data member of type Customer, the DataContractSerializer is allowed to load the Customer type when it deserializes this data member.

Darüber hinaus unterstützt DataContractSerializer Polymorphie.Additionally, the DataContractSerializer supports polymorphism. Ein Datenmember kann als Objectdeklariert werden, die eingehenden Daten können jedoch eine Customer -Instanz enthalten.A data member may be declared as Object, but the incoming data may contain a Customer instance. Das ist nur möglich, wenn der Customer -Typ für das Deserialisierungsprogramm anhand einer der folgenden Mechanismen "bekannt" gemacht wurde:This is possible only if the Customer type has been made "known" to the deserializer through one of these mechanisms:

  • KnownTypeAttribute -Attribut wird auf einen Typ angewendet.KnownTypeAttribute attribute applied to a type.

  • KnownTypeAttribute -Attribut gibt eine Methode an, die eine Liste mit Typen zurückgibt.KnownTypeAttribute attribute specifying a method that returns a list of types.

  • ServiceKnownTypeAttribute -Attribut.ServiceKnownTypeAttribute attribute.

  • KnownTypes -Konfigurationsabschnitt.The KnownTypes configuration section.

  • Eine Liste bekannter Typen wird bei direkter Verwendung des Serialisierungsprogramm während der Erstellung explizit an DataContractSerializer übergeben.A list of known types explicitly passed to the DataContractSerializer during construction, if using the serializer directly.

Jede dieser Mechanismen erhöht die Angriffsfläche, da sie die Anzahl der Typen erhöhen, die das Deserialisierungsprogramm laden kann.Each of these mechanisms increases the surface area by introducing more types that the deserializer can load. Überprüfen Sie diese Mechanismen und stellen Sie sicher, dass der Liste der bekannten Typen keine unerwünschten Typen hinzugefügt werden.Control each of these mechanisms to ensure no malicious or unintended types are added to the known types list.

Sobald sich ein bekannter Typ im Bereich befindet, kann er jederzeit geladen und Instanzen des Typs erstellt werden, selbst wenn der Vertag dessen Verwendung an sich verbietet.Once a known type is in scope, it can be loaded at any time, and instances of the type can be created, even if the contract forbids actually using it. Angenommen, der Typ "MyDangerousType" wird über einen dieser Mechanismen der Liste der bekannten Typen hinzugefügt.For example, suppose the type "MyDangerousType" is added to the known types list using one of the mechanisms above. Dies bedeutet Folgendes:This means that:

  • MyDangerousType wird geladen und sein Klassenkonstruktor wird ausgeführt.MyDangerousType is loaded and its class constructor runs.

  • Auch wenn nur ein Datenvertrag mit einem Zeichenfolgendatenmember deserialisiert wird, kann eine böswillige Nachricht dazu führen, dass eine Instanz von MyDangerousType erstellt wird.Even when deserializing a data contract with a string data member, a malicious message may still cause an instance of MyDangerousType to create. Code in MyDangerousType, z. B. ein Eigenschaftensetter, wird möglicherweise ausgeführt.Code in MyDangerousType, such as property setters, may run. Anschließend versucht das Deserialisierungsprogramm diese Instanz dem Zeichenfolgendatenmember zuzuordnen, schlägt fehl und löst eine Ausnahme aus.After this is done, the deserializer tries to assign this instance to the string data member and fail with an exception.

Wenn Sie eine Methode schreiben, die eine Liste bekannter Typen zurückgibt, oder wenn Sie eine Liste direkt an den DataContractSerializer -Konstruktor übergeben, stellen Sie sicher, dass der Code zum Erstellen der Liste sicher ist und nur vertrauenswürdige Daten heranzieht.When writing a method that returns a list of known types, or when passing a list directly to the DataContractSerializer constructor, ensure that the code that prepares the list is secure and operates only on trusted data.

Wenn Sie bekannte Typen in Konfiguration angeben, stellen Sie sicher, dass die Konfigurationsdatei sicher ist.If specifying known types in configuration, ensure that the configuration file is secure. Verwenden Sie stets starke Namen in der Konfiguration, indem Sie den öffentlichen Schlüssel der signierten Assembly angeben, in der sich der Typ befindet. Geben Sie jedoch nicht die Version des zu ladenden Typs an.Always use strong names in configuration (by specifying the public key of the signed assembly where the type resides), but do not specify the version of the type to load. Das Typladeprogramm wählt die neueste Version wenn möglich automatisch aus.The type loader automatically picks the latest version, if possible. Die Angabe einer bestimmten Version in der Konfiguration birgt folgendes Risiko: Falls ein Typ eine Sicherheitslücke aufweist, die eine spätere Version möglicherweise beseitigt, wird trotzdem die gefährdete Version geladen, da sie in der Konfiguration ausdrücklich angegeben ist.If you specify a particular version in configuration, you run the following risk: A type may have a security vulnerability that may be fixed in a future version, but the vulnerable version still loads because it is explicitly specified in configuration.

Zu viele bekannte Typen haben eine weitere Konsequenz: DataContractSerializer erstellt einen Cache mit Serialisierungs-/Deserialisierungscode in der Anwendungsdomäne. Dabei erhält jeder zu serialisierende und zu deserialisierende Typ einen Eintrag.Having too many known types has another consequence: The DataContractSerializer creates a cache of serialization/deserialization code in the application domain, with an entry for each type it must serialize and deserialize. Dieser Cache wird nie gelöscht, solange die Anwendungsdomäne ausgeführt wird.This cache is never cleared as long as the application domain is running. Folglich kann ein Angreifer, dem die Verwendung vieler bekannter Typen in einer Anwendung bekannt ist, die Deserialisierung all dieser Typen veranlassen, wodurch der Cache außerordentlich viel Arbeitsspeicher verbraucht.Therefore, an attacker who is aware that an application uses many known types can cause the deserialization of all these types, causing the cache to consume a disproportionately large amount of memory.

Verhindern eines unerwünschter Zustands der TypenPreventing Types from Being in an Unintended State

Ein Typ besitzt möglicherweise interne Konsistenzeinschränkungen, die beachtet werden müssen.A type may have internal consistency constraints that must be enforced. Diese Einschränkungen dürfen bei der Deserialisierung nicht außer Kraft gesetzt werden.Care must be taken to avoid breaking these constraints during deserialization.

Im folgenden Beispiel wird der Zustand einer Luftschleuse in einer Raumsonde dargestellt. Dabei gilt die Einschränkung, dass beide Türen nicht gleichzeitig geöffnet werden können.The following example of a type represents the state of an airlock on a spacecraft, and enforces the constraint that both the inner and the outer doors cannot be open at the same time.

[DataContract]
public class SpaceStationAirlock
{
    [DataMember]
    private bool innerDoorOpenValue = false;
    [DataMember]
    private bool outerDoorOpenValue = false;

    public bool InnerDoorOpen
    {
        get { return innerDoorOpenValue; }
        set
        {
            if (value & outerDoorOpenValue)
                throw new Exception("Cannot open both doors!");
            else innerDoorOpenValue = value;
        }
    }
    public bool OuterDoorOpen
    {
        get { return outerDoorOpenValue; }
        set
        {
            if (value & innerDoorOpenValue)
                throw new Exception("Cannot open both doors!");
            else outerDoorOpenValue = value;
        }
    }
}
<DataContract()> _
Public Class SpaceStationAirlock
    <DataMember()> Private innerDoorOpenValue As Boolean = False
    <DataMember()> Private outerDoorOpenValue As Boolean = False

    Public Property InnerDoorOpen() As Boolean
        Get

            Return innerDoorOpenValue
        End Get
        Set(ByVal value As Boolean)
            If (value & outerDoorOpenValue) Then
                Throw New Exception("Cannot open both doors!")
            Else
                innerDoorOpenValue = value
            End If
        End Set
    End Property

    Public Property OuterDoorOpen() As Boolean
        Get
            Return outerDoorOpenValue
        End Get
        Set(ByVal value As Boolean)
            If (value & innerDoorOpenValue) Then
                Throw New Exception("Cannot open both doors!")
            Else 
                outerDoorOpenValue = value
            End If
        End Set
    End Property
End Class

Ein Angreifer kann folgende böswillige Nachricht senden, um die Einschränkungen zu umgehen und das Objekt in einen ungültigen Zustand zu versetzen, der unerwünschte und unvorhersehbare Folgen haben kann.An attacker may send a malicious message like this, getting around the constraints and getting the object into an invalid state, which may have unintended and unpredictable consequences.

<SpaceStationAirlock>  
    <innerDoorOpen>true</innerDoorOpen>  
    <outerDoorOpen>true</outerDoorOpen>  
</SpaceStationAirlock>  

Diese Situation ist vermeidbar, wenn folgenden Punkte beachtet werden:This situation can be avoided by being aware of the following points:

  • Wenn DataContractSerializer Klassen deserialisiert, werden in den meisten Fällen keine Konstruktoren ausgeführt.When the DataContractSerializer deserializes most classes, constructors do not run. Verlassen Sie sich deshalb nicht darauf, dass der Konstruktor Zustände verwaltet.Therefore, do not rely on any state management done in the constructor.

  • Verwenden Sie Rückrufe, um sicherzustellen, dass sich das Objekt in einem gültigen Zustand befindet.Use callbacks to ensure that the object is in a valid state. Der mit dem OnDeserializedAttribute -Attribut gekennzeichnete Rückruf ist besonders hilfreich, wenn er nach Abschluss der Deserialisierung ausgeführt wird und den Gesamtzustand überprüfen und korrigieren kann.The callback marked with the OnDeserializedAttribute attribute is especially useful because it runs after deserialization is complete and has a chance to examine and correct the overall state. Weitere Informationen finden Sie unter versionstolerante Serialisierungsrückrufe.For more information, see Version-Tolerant Serialization Callbacks.

  • Entwerfen Sie Datenvertragstypen nicht nach einer bestimmten Reihenfolge, in der Eigenschaftensetter aufgerufen werden müssen.Do not design data contract types to rely on any particular order in which property setters must be called.

  • Seien Sie vorsichtig, wenn Sie ältere Typen verwenden, die mit dem SerializableAttribute -Attribut gekennzeichnet sind.Take care using legacy types marked with the SerializableAttribute attribute. Viele davon wurden für .NET Framework.NET Framework Remoting zur ausschließlichen Verwendung mit vertrauenswürdigen Daten entwickelt.Many of them were designed to work with .NET Framework.NET Framework remoting for use with trusted data only. Bei der Entwicklung vorhandener Typen, die mit diesem Attribut gekennzeichnet sind, spielte die Sicherheit möglicherweise keine Rolle.Existing types marked with this attribute may not have been designed with state safety in mind.

  • Verlassen Sie sich nicht darauf, dass die IsRequired -Eigenschaft des DataMemberAttribute -Attributs das Vorhandensein von Daten in einem sicheren Zustand garantiert.Do not rely on the IsRequired property of the DataMemberAttribute attribute to guarantee presence of data as far as state safety is concerned. Deren Status könnte auch null, zero oder invalid lauten.Data could always be null, zero, or invalid.

  • Vertrauen Sie niemals einem Objektdiagramm, das von einer nicht vertrauenswürdigen Datenquelle deserialisiert wurde, ohne es zuerst zu überprüfen.Never trust an object graph deserialized from an untrusted data source without validating it first. Zwar kann sich jedes einzelne Objekt in einem konsistenten Zustand befinden, das Objektdiagramm insgesamt vielleicht jedoch nicht.Each individual object may be in a consistent state, but the object graph as a whole may not be. Außerdem kann es sein, dass selbst bei deaktiviertem Objektdiagramm-Beibehaltungsmodus das deserialisierte Diagramm in einem Zirkelverweis noch mehrere Verweise auf das selbe Objekt aufweist.Furthermore, even if the object graph preservation mode is disabled, the deserialized graph may have multiple references to the same object or have circular references. Weitere Informationen finden Sie unter Serialisierung und Deserialisierung.For more information, see Serialization and Deserialization.

Sicheres Verwenden von NetDataContractSerializerUsing the NetDataContractSerializer Securely

NetDataContractSerializer ist ein Serialisierungsmodul, das eng verknüpfte Typen verwendet.The NetDataContractSerializer is a serialization engine that uses tight coupling to types. Das ist mit BinaryFormatter und SoapFormattervergleichbar.This is similar to the BinaryFormatter and the SoapFormatter. Das heißt, der zu instanziierende Typ wird ermittelt, indem die .NET Framework.NET Framework -Assembly und der Typnamen in den eingehenden Daten gelesen wird.That is, it determines which type to instantiate by reading the .NET Framework.NET Framework assembly and type name from the incoming data. Obwohl es sich um einen Teil von WCF ist, besteht keine Möglichkeit, dieses Serialisierungsmodul anschließen; benutzerdefinierter Code muss geschrieben werden.Although it is a part of WCF, there is no supplied way of plugging in this serialization engine; custom code must be written. Die NetDataContractSerializer dient in erster Linie zum vereinfachen die Migration von .NET Framework.NET Framework Remoting und WCF.The NetDataContractSerializer is provided primarily to ease migration from .NET Framework.NET Framework remoting to WCF. Weitere Informationen finden Sie unter dem entsprechenden Abschnitt unter Serialisierung und Deserialisierung.For more information, see the relevant section in Serialization and Deserialization.

Da die Nachricht selbst möglicherweise alle ladbaren Typen angibt, ist der NetDataContractSerializer -Mechanismus grundsätzlich unsicher und sollte nur mit vertrauenswürdigen Daten verwendet werden.Because the message itself may indicate any type can be loaded, the NetDataContractSerializer mechanism is inherently insecure and should be used only with trusted data. Sie können den Mechanismus sichern, indem Sie einen sicheren, Typen einschränkenden Typbinder schreiben, der nur das Laden sicherer Typen zulässt (mithilfe der Binder -Eigenschaft).It is possible to make it secure by writing a secure, type-limiting type binder that allows only safe types to load (using the Binder property).

Selbst wenn das Modul mit vertrauenswürdigen Daten arbeitet, geben die eingehenden Daten möglicherweise den zu ladenden Typ nur ungenau an, insbesondere, wenn die AssemblyFormat -Eigenschaft auf Simplefestgelegt ist.Even when used with trusted data, the incoming data may insufficiently specify the type to load, especially if the AssemblyFormat property is set to Simple. Jeder, der Zugriff auf das Verzeichnis der Anwendung oder den globalen Assemblycache besitzt, kann den vorhandenen zu ladenden Typ durch einen schädlichen Typ ersetzen.Anyone with access to the application’s directory or to the global assembly cache can substitute a malicious type in place of the one that is supposed to load. Stellen Sie stets sicher, dass das Verzeichnis der Anwendung und der globale Anwendungscache gesichert sind, indem Sie die Berechtigungen richtig festlegen.Always ensure the security of your application’s directory and of the global assembly cache by correctly setting permissions.

Im Allgemeinen gilt: Wenn Sie teilweise vertrauenswürdigem Code erlauben, auf Ihre NetDataContractSerializer -Instanz zuzugreifen oder auf andere Weise den Ersatzselektor (ISurrogateSelector) bzw. den Serialisierungsbinder (SerializationBinder) zu steuern, kann er möglicherweise einen großen Teil des Serialisierungs-/Deserialisierungsprozesses steuern.In general, if you allow partially trusted code access to your NetDataContractSerializer instance or otherwise control the surrogate selector (ISurrogateSelector) or the serialization binder (SerializationBinder), the code may exercise a great deal of control over the serialization/deserialization process. Er kann beispielsweise beliebige Typen einfügen, was zur Offenlegung von Informationen führt, oder das sich ergebende Objektdiagramm und die serialisierten Daten manipulieren bzw. einen Überlauf des resultierenden serialisierten Streams herbeiführen.For example, it may inject arbitrary types, lead to information disclosure, tamper with the resulting object graph or serialized data, or overflow the resultant serialized stream.

Ein weiteres Sicherheitsproblem bei NetDataContractSerializer stellen Denial-of-Service-Angriffe dar, nicht die Gefahr durch das Ausführen von schädlichem Code.Another security concern with the NetDataContractSerializer is a denial of service, not a malicious code execution threat. Legen Sie bei der Verwendung von NetDataContractSerializerdas MaxItemsInObjectGraph -Kontingent immer auf einen sicheren Wert fest.When using the NetDataContractSerializer, always set the MaxItemsInObjectGraph quota to a safe value. Eine kleine böswillige Nachricht kann leicht erstellt werden, die ein Array von Objekten zuordnet, deren Größe nur durch dieses Kontingent eingeschränkt werden kann.It is easy to construct a small malicious message that allocates an array of objects whose size is limited only by this quota.

Spezielle Bedrohungen bei XmlSerializerXmlSerializer-Specific Threats

Das XmlSerializer -Sicherheitsmodell ähnelt dem von DataContractSerializer.The XmlSerializer security model is similar to that of the DataContractSerializer. Einige Bedrohungen sind jedoch speziell bei XmlSerializerrelevant.A few threats, however, are unique to the XmlSerializer.

XmlSerializer generiert zur Laufzeit Serialisierungsassemblys mit Code, der die eigentliche Serialisierung und Deserialisierung ausführt. Diese Assemblys werden in einem temporären Dateiverzeichnis erstellt.The XmlSerializer generates serialization assemblies at runtime that contain code that actually serializes and deserializes; these assemblies are created in a temporary files directory. Wenn ein anderer Prozess oder Benutzer Zugriffrechte für dieses Verzeichnis besitzt, kann er den Serialisierungs-/Deserialisierungscode mit beliebigem Code überschreiben.If some other process or user has access rights to that directory, they may overwrite the serialization/deserialization code with arbitrary code. XmlSerializer führt dann diesen Code mit dessen Sicherheitskontext anstelle des Serialisierungs-/Deserialisierungscode aus.The XmlSerializer then runs this code using its security context, instead of the serialization/deserialization code. Stellen Sie sicher, dass die Berechtigungen für das temporäre Dateiverzeichnis richtig festgelegt sind, um dieses Szenario zu verhindern.Make sure the permissions are set correctly on the temporary files directory to prevent this from happening.

XmlSerializer besitzt außerdem einen Modus, in dem Serialisierungsassemblys nicht zur Laufzeit generiert werden, sondern bereits generierte Serialisierungsassemblys verwendet werden.The XmlSerializer also has a mode in which it uses pre-generated serialization assemblies instead of generating them at runtime. Dieser Modus wird immer dann ausgelöst, wenn XmlSerializer eine geeignete Serialisierungsassembly findet.This mode is triggered whenever the XmlSerializer can find a suitable serialization assembly. XmlSerializer überprüft, ob die Serialisierungsassembly mit demselben Schlüssel signiert wurde wie die Assembly, die die zu serialisierenden Typen enthält.The XmlSerializer checks whether or not the serialization assembly was signed by the same key that was used to sign the assembly that contains the types being serialized. Dies dient als Schutz vor schädlichen Assemblys, die als Serialisierungsassemblys getarnt sind.This offers protection from malicious assemblies being disguised as serialization assemblies. Wenn die Assembly mit den serialisierbaren Typen jedoch nicht signiert ist, kann XmlSerializer diese Überprüfung nicht ausführen und verwendet eine beliebige Assembly mit dem richtigen Namen.However, if the assembly that contains your serializable types is not signed, the XmlSerializer cannot perform this check and uses any assembly with the correct name. Auf diese Weise kann schädlicher Code ausgeführt werden.This makes running malicious code possible. Signieren Sie stets die Assemblys, die die serialisierbaren Typen enthalten, oder schränken Sie den Zugriff auf das Verzeichnis der Anwendung und den globalen Assemblycache stark ein, um das Eindringen von schädlichen Assemblys zu verhindern.Always sign the assemblies that contain your serializable types, or tightly control access to your application’s directory and the global assembly cache to prevent the introduction of malicious assemblies.

XmlSerializer kann einem Denial-of-Service-Angriff ausgesetzt sein.The XmlSerializer can be subject to a denial of service attack. XmlSerializer verfügt über kein MaxItemsInObjectGraph -Kontingent (wie es bei DataContractSerializervorhanden ist).The XmlSerializer does not have a MaxItemsInObjectGraph quota (as is available on the DataContractSerializer). Deshalb wird eine beliebige Anzahl von Objekten deserialisiert, die nur durch die Nachrichtengröße eingeschränkt wird.Thus, it deserializes an arbitrary amount of objects, limited only by the message size.

Bedrohungen durch teilweise vertrauenswürdigen CodePartial Trust Threats

Berücksichtigen Sie beim Ausführen von teilweise vertrauenswürdigem Code die folgenden Überlegungen zu den damit verbundenen Bedrohungen.Note the following concerns regarding threats related to code running with partial trust. Zu diesen Bedrohungen gehören enthaltener schädlicher Code ebenso wie schädlicher Code in Verbindung mit anderen Angriffsszenarien (z. B. teilweise vertrauenswürdiger Code, der eine bestimmte Zeichenfolge enthält und diese anschließend deserialisiert).These threats include malicious partially-trusted code as well as malicious partially-trusted code in combination with other attack scenarios (for example, partially-trusted code that constructs a specific string and then deserializing it).

  • Bestätigen Sie bei der Verwendung irgendwelcher Serialisierungskomponenten niemals im Voraus Berechtigungen, selbst wenn die gesamte Serialisierung innerhalb des Assertionsbereichs stattfindet und nur vertrauenswürdige Daten oder Objekte behandelt werden.When using any serialization components, never assert any permissions before such usage, even if the entire serialization scenario is within the scope of your assert, and you are not dealing with any untrusted data or objects. Eine solche Vorgehensweise könnte zu Sicherheitslücken führen.Such usage may lead to security vulnerabilities.

  • In Fällen, in denen teilweise vertrauenswürdiger Code entweder über Erweiterungspunkte (Ersatzzeichen), über zu serialisierende Typen oder über andere Mittel den Serialisierungsprozess bestimmt, kann dieser teilweise vertrauenswürdige Code bewirken, dass das Serialisierungsprogramm eine große Datenmenge in den serialisierten Stream ausgibt, was einen Denial-of-Service (DoS) beim Empfänger dieses Streams bewirken kann.In cases where partially-trusted code has control over the serialization process, either through extensibility points (surrogates), types being serialized, or through other means, the partially-trusted code may cause the serializer to output a large amount of data into the serialized stream, which may cause Denial of Service (DoS) to the receiver of this stream. Wenn Sie Daten serialisieren, die für ein Ziel bestimmt sind, das für DoS-Angriffe anfällig ist, dann serialisieren Sie keine teilweise vertrauenswürdigen Typen und lassen Sie nicht zu, dass teilweise vertrauenswürdiger Code die Serialisierung irgendwie steuert.If you are serializing data intended for a target that is sensitive to DoS threats, do not serialize partially-trusted types or otherwise let partially-trusted code control serialization.

  • Wenn Sie zulassen, dass teilweise vertrauenswürdiger Codezugriff auf Ihre DataContractSerializer -Instanz ein, oder andernfalls steuern die Datenvertrag-Ersatzzeichen, kann es viel Serialisierungs-/Deserialisierungsprozesses ausüben.If you allow partially-trusted code access to your DataContractSerializer instance or otherwise control the Data Contract Surrogates, it may exercise a great deal of control over the serialization/deserialization process. Er kann beispielsweise beliebige Typen einfügen, was zur Offenlegung von Informationen führt, oder das sich ergebende Objektdiagramm und die serialisierten Daten manipulieren bzw. einen Überlauf des resultierenden serialisierten Streams herbeiführen.For example, it may inject arbitrary types, lead to information disclosure, tamper with the resulting object graph or serialized data, or overflow the resultant serialized stream. Eine entsprechende NetDataContractSerializer -Bedrohung wird im Abschnitt "Sicheres Verwenden von NetDataContractSerializer" beschrieben.An equivalent NetDataContractSerializer threat is described in the "Using the NetDataContractSerializer Securely" section.

  • Wenn das DataContractAttribute -Attribut auf einen Typ angewendet wird (oder der Typ als [Serializable] gekennzeichnet wird, ohne ISerializablezu sein), kann das Deserialisierungsprogramm eine Instanz eines solchen Typs selbst dann erstellen, wenn alle Konstruktoren durch Aufrufe nicht öffentlich und/oder geschützt sind.If the DataContractAttribute attribute is applied to a type (or the type marked as [Serializable] but is not ISerializable), the deserializer can create an instance of such a type even if all constructors are non-public or protected by demands.

  • Vertrauen Sie niemals dem Ergebnis der Deserialisierung, es sei denn , die Daten können als vertrauenswürdig eingestuft werden und Sie sind sicher, dass alle bekannten Typen vertrauenswürdige Typen sind.Never trust the result of deserialization unless the data to be deserialized is trusted and you are certain that all known types are types that you trust. Beachten Sie, dass bei Ausführung unter teilweiser Vertrauenswürdigkeit bekannte Typen nicht aus der Anwendungskonfigurationsdatei, sondern aus der Computerkonfigurationsdatei geladen werden.Note that known types are not loaded from the application configuration file, (but are loaded from the computer configuration file) when running in partial trust.

  • Wenn Sie eine DataContractSerializer -Instanz mit einem Ersatzselektor übergeben, der im teilweise vertrauenswürdigen Modus hinzugefügt wurde, kann der Code alle änderbaren Einstellungen dieses Ersatzselektors ändern.If you pass a DataContractSerializer instance with a surrogate added to partially-trusted code, the code can change any modifiable settings on that surrogate.

  • Wenn ein XML-Reader (oder die enthaltenen Daten) auf teilweise vertrauenswürdigem Code basiert, dann betrachten Sie das resultierende deserialisierte Objekt als nicht vertrauenswürdige Daten.For a deserialized object, if the XML reader (or the data therein) comes from partially-trusted code, treat the resulting deserialized object as untrusted data.

  • Der Umstand, dass der ExtensionDataObject -Typ keine öffentlichen Member besitzt, bedeutet nicht, dass die darin enthaltenen Daten sicher sind.The fact that the ExtensionDataObject type has no public members does not mean that data within it is secure. Wenn Sie z.&#160;B. eine Deserialisierung aus einer privilegierten Datenquelle in ein Objekt ausführen, in dem sich einige Daten befinden, und dieses Objekt anschließend an teilweise vertrauenswürdigen Code übergeben, kann dieser Code die Daten in ExtensionDataObject lesen, indem er das Objekt serialisiert.For example, if you deserialize from a privileged data source into an object in which some data resides, then hand that object to partially-trusted code, the partially-trusted code can read the data in the ExtensionDataObject by serializing the object. Legen Sie bei einer Deserialisierung aus einer privilegierten Datenquelle in ein Objekt, das später an teilweise vertrauenswürdigen Code übergeben wird, wenn möglich die IgnoreExtensionDataObject -Einstellung auf true fest.Consider setting IgnoreExtensionDataObject to true when deserializing from a privileged data source into an object that is later passed to partially-trusted code.

  • DataContractSerializer und DataContractJsonSerializer unterstützen die Serialisierung von privaten, geschützten, internen und öffentlichen Membern mit vollständiger Vertrauenswürdigkeit.DataContractSerializer and DataContractJsonSerializer support the serialization of private, protected, internal, and public members in full trust. Bei teilweiser Vertrauenswürdigkeit können jedoch nur öffentliche Member serialisiert werden.However, in partial trust, only public members can be serialized. Wenn eine Anwendung versucht, einen nicht öffentlichen Member zu serialisieren, wird eine SecurityException ausgelöst.A SecurityException is thrown if an application attempts to serialize a non-public member.

    Verwenden Sie das System.Runtime.CompilerServices.InternalsVisibleTo -Assemblyattribut, um zuzulassen, dass interne oder geschützte interne Member serialisiert werden können.To allow internal or protected internal members to be serialized in partial trust, use the System.Runtime.CompilerServices.InternalsVisibleTo assembly attribute. Dieses Attribut ermöglicht es einer Assembly zu deklarieren, dass eigene interne Member in anderen Assemblys sichtbar sein sollen.This attribute allows an assembly to declare that its internal members are visible to some other assembly. In diesem Fall deklariert eine Assembly, deren interne Member serialisiert werden sollen, dass ihre internen Member für System.Runtime.Serialization.dll sichtbar sein sollen.In this case, an assembly that wants to have its internal members serialized declares that its internal members are visible to System.Runtime.Serialization.dll.

    Der Vorteil dieser Vorgehensweise besteht darin, dass kein Codegenerierungspfad mit erweiterten Berechtigungen erforderlich ist.The advantage of this approach is that it does not require an elevated code generation path.

    Gleichzeitig sind jedoch zwei gravierende Nachteile zu beachten.At the same time, there are two major disadvantages.

    Der erste Nachteil besteht darin, dass die Opt-In-Eigenschaft des InternalsVisibleTo -Attributs assemblyweit festgelegt ist.The first disadvantage is that the opt-in property of the InternalsVisibleTo attribute is assembly-wide. Das heißt, Sie können nicht angeben, dass nur die internen Member einer bestimmten Klasse serialisiert werden sollen.That is, you cannot specify that only a certain class can have its internal members serialized. Natürlich können Sie immer noch festlegen, dass ein bestimmter interner Member nicht serialisiert werden soll, indem Sie dem betreffenden Member einfach kein DataMember -Attribut hinzufügen.Of course, you can still choose not to serialize a specific internal member, by simply not adding a DataMember attribute to that member. Ebenso können Entwickler angeben, dass ein Member intern und nicht privat oder geschützt ist, wobei jedoch geringe Nachteile in Bezug auf die Sichtbarkeit zu erwarten sind.Similarly, a developer can also choose to make a member internal rather than private or protected, with slight visibility concerns.

    Der zweite Nachteil besteht darin, dass nach wie vor keine privaten und geschützten Member unterstützt werden.The second disadvantage is that it still does not support private or protected members.

    Betrachten Sie das folgende Programm, das die Verwendung des InternalsVisibleTo -Attributs bei teilweiser Vertrauenswürdigkeit veranschaulicht:To illustrate the use of the InternalsVisibleTo attribute in partial trust, consider the following program:

        public class Program
        {
            public static void Main(string[] args)
            {
                try
                {
    //              PermissionsHelper.InternetZone corresponds to the PermissionSet for partial trust. 
    //              PermissionsHelper.InternetZone.PermitOnly();
                    MemoryStream memoryStream = new MemoryStream();
                    new DataContractSerializer(typeof(DataNode)).
                        WriteObject(memoryStream, new DataNode());
                }
                finally
                {
                    CodeAccessPermission.RevertPermitOnly();
                }
            }
    
            [DataContract]
            public class DataNode
            {
                [DataMember]
                internal string Value = "Default";
            }
        }
    

    Im obigen Beispiel entspricht PermissionsHelper.InternetZone dem PermissionSet für teilweise Vertrauenswürdigkeit.In the example above, PermissionsHelper.InternetZone corresponds to the PermissionSet for partial trust. Ohne InternalsVisibleToAttributetritt nun ein Anwendungsfehler auf, wobei eine SecurityException ausgelöst wird, die angibt, dass nicht öffentliche Member mit teilweiser Vertrauenswürdigkeit nicht serialisiert werden können.Now, without InternalsVisibleToAttribute, the application will fail, throwing a SecurityException indicating that non-public members cannot be serialized in partial trust.

    Wenn jedoch der Quelldatei die folgende Zeile hinzugefügt wird, wird das Programm erfolgreich ausgeführt.However, if we add the following line to the source file, the program runs successfully.

    [assembly:System.Runtime.CompilerServices.InternalsVisibleTo("System.Runtime.Serialization, PublicKey = 00000000000000000400000000000000")]
    

Weitere Überlegungen zur ZustandsverwaltungOther State Management Concerns

Es gibt noch einige Überlegungen zur Verwaltung von Objektzuständen, die erwähnt werden sollten:A few other concerns regarding object state management are worth mentioning:

  • Bei der Verwendung eines auf Streams basierenden Programmiermodells mit einem Streamingtransport findet die Verarbeitung der Nachricht statt, sobald sie eingeht.When using the stream-based programming model with a streaming transport, processing of the message occurs as the message arrives. Der Absender der Nachricht kann den Sendevorgang in der Mitte des Streams abbrechen, wodurch Ihr Code einen unvorhersehbaren Zustand annimmt, falls mehr Inhalt erwartet wurde.The sender of the message may abort the send operation in the middle of the stream, leaving your code in an unpredictable state if more content was expected. Verlassen Sie sich im Allgemeinen nicht darauf, dass Streams abgeschlossen werden, und führen Sie keine Arbeiten in einem streambasierten Vorgang aus, für die im Fall eines abgebrochenen Streams kein Rollback erfolgen kann.In general, do not rely on the stream being complete, and do not perform any work in a stream-based operation that cannot be rolled back in case the stream is aborted. Das gilt auch für den Fall, dass eine Nachricht nach dem Streamingtext falsch formatiert ist (es fehlt z. B. ein Endtag für den SOAP-Umschlag oder es ist ein zweiter Nachrichtentext vorhanden).This also applies to the situation where a message may be malformed after the streaming body (for example, it may be missing an end tag for the SOAP envelope or may have a second message body).

  • Mit der IExtensibleDataObject -Funktion werden möglicherweise vertrauliche Daten ausgegeben.Using the IExtensibleDataObject feature may cause sensitive data to be emitted. Wenn Sie Daten aus einer nicht vertrauenswürdigen Quelle in Datenverträgen mit IExtensibleObjectData zulassen und später über einen sicheren Kanal neu ausgeben, in dem Nachrichten signiert sind, bürgen Sie womöglich für völlig unbekannte Daten.If you are accepting data from an untrusted source into data contracts with IExtensibleObjectData and later re-emitting it on a secure channel where messages are signed, you are potentially vouching for data you know nothing about. Darüber hinaus sind vielleicht die gesendeten Daten insgesamt ungültig, wenn Sie sowohl die bekannten als auch die unbekannten Teile der Daten in Betracht ziehen.Moreover, the overall state you are sending may be invalid if you take both the known and unknown pieces of data into account. Vermeiden Sie diese Situation, indem Sie entweder die Eigenschaft der Erweiterungsdaten selektiv auf null festlegen oder indem Sie selektiv die IExtensibleObjectData -Funktion deaktivieren.Avoid this situation by either selectively setting the extension data property to null or by selectively disabling the IExtensibleObjectData feature.

SchemaimportSchema Import

Normalerweise wird ein Schema zum Generieren von Typen nur zur Entwurfszeit importiert, beispielsweise, wenn Sie mit dem ServiceModel Metadata Utility Tool (Svcutil.exe) eine Clientklasse für einen Webdienst generieren.Normally, the process of importing schema to generate types happens only at design time, for example, when using the ServiceModel Metadata Utility Tool (Svcutil.exe) on a Web service to generate a client class. In komplexeren Szenarien jedoch verarbeiten Sie ein Schema vielleicht auch zur Laufzeit.However, in more advanced scenarios, you may process schema at runtime. Seien Sie sich jedoch bewusst, dass dabei das Risiko von Denial-of-Service-Angriffen besteht.Be aware that doing so can expose you to denial-of-service risks. Bei einigen Schemas dauert das Importieren sehr lange.Some schema may take a long time to be imported. Verwenden Sie in solchen Szenarien niemals die Schemaimportkomponente von XmlSerializer , falls Schemas von einer nicht vertrauenswürdigen Quelle stammen könnten.Never use the XmlSerializer schema import component in such scenarios if schemas are possibly coming from an untrusted source.

Spezielle Bedrohungen bei der ASP.NET AJAX-IntegrationThreats Specific to ASP.NET AJAX Integration

Wenn der Benutzer implementiert WebScriptEnablingBehavior oder WebHttpBehavior, WCF macht einen Endpunkt, der sowohl XML-als auch JSON-Nachrichten akzeptieren kann.When the user implements WebScriptEnablingBehavior or WebHttpBehavior, WCF exposes an endpoint that can accept both XML and JSON messages. Es gibt jedoch nur einen Satz von Readerkontingenten, der sowohl vom XML-Reader als auch von JSON-Reader verwendet wird.However, there is only one set of reader quotas, used both by the XML reader and the JSON reader. Einige Kontingenteinstellungen sind möglicherweise für einen Reader geeignet, aber zu groß für den anderen.Some quota settings may be appropriate for one reader but too large for the other.

Mit der Implementierung von WebScriptEnablingBehaviorhat der Benutzer die Möglichkeit, beim Endpunkt einen JavaScript-Proxy verfügbar zu machen.When implementing WebScriptEnablingBehavior, the user has the option to expose a JavaScript proxy at the endpoint. Die folgenden Sicherheitsprobleme müssen beachtet werden:The following security issues must be considered:

  • Informationen über den Dienst (Vorgangsnamen, Parameternamen usw.) können abgerufen werden, indem der JavaScript-Proxy überprüft wird.Information about the service (operation names, parameter names, and so on) can be obtained by examining the JavaScript proxy.

  • Wird der JavaScript-Endpunkt verwendet, bleiben möglicherweise vertrauliche und private Informationen im Webbrowsercache des Clients gespeichert.When using the JavaScript endpoint, sensitive and private information might be retained in the client Web browser cache.

Hinweis zu KomponentenA Note on Components

WCF ist ein flexibles, anpassbares System.WCF is a flexible and customizable system. Die meisten der Inhalt dieses Themas konzentrieren sich auf die häufigsten Szenarien für die Verwendung von WCF.Most of the contents of this topic focus on the most common WCF usage scenarios. Allerdings ist es möglich, die Komponenten können auf viele verschiedene Arten WCF bietet.However, it is possible to compose components WCF provides in many different ways. Deshalb sollten Sie wissen, welche Auswirkung die Verwendung der einzelnen Komponenten auf die Sicherheit hat.It is important to understand the security implications of using each component. Insbesondere:In particular:

  • Wenn XML-Reader notwendig sind, verwenden Sie nur die Reader der XmlDictionaryReader -Klasse.When you must use XML readers, use the readers the XmlDictionaryReader class provides as opposed to any other readers. Sichere Reader werden mit den Methoden CreateTextReader, CreateBinaryReaderoder CreateMtomReader erstellt.Safe readers are created using CreateTextReader, CreateBinaryReader, or CreateMtomReader methods. Verwenden Sie nicht die Create -Methode.Do not use the Create method. Konfigurieren Sie die Reader immer mit sicheren Kontingenten.Always configure the readers with safe quotas. Die Module Serialisierung in WCF sind nur bei einer Verwendung mit sicheren XML-Reader von WCF verwendet.The serialization engines in WCF are secure only when used with secure XML readers from WCF.

  • Wenn Sie potenziell nicht vertrauenswürdige Daten mit DataContractSerializer deserialisieren, legen Sie immer die MaxItemsInObjectGraph -Eigenschaft fest.When using the DataContractSerializer to deserialize potentially untrusted data, always set the MaxItemsInObjectGraph property.

  • Legen Sie beim Erstellen einer Nachricht den maxSizeOfHeaders -Parameter fest, falls MaxReceivedMessageSize keinen ausreichenden Schutz bietet.When creating a message, set the maxSizeOfHeaders parameter if MaxReceivedMessageSize does not offer enough protection.

  • Wenn Sie einen Encoder erstellen, konfigurieren Sie stets die relevanten Kontingente, z. B. MaxSessionSize und MaxBufferSize.When creating an encoder, always configure the relevant quotas, such as MaxSessionSize and MaxBufferSize.

  • Legen Sie bei Verwendung eines XPath-Nachrichtenfilters NodeQuota fest, um die Menge der XML-Knoten einzuschränken, die der Filter durchläuft.When using an XPath message filter, set the NodeQuota to limit the amount of XML nodes the filter visits. Verwenden Sie keine XPath-Ausdrücke, deren Berechnung lange dauert, ohne dass viele Knoten durchlaufen werden.Do not use XPath expressions that could take a long time to compute without visiting many nodes.

  • Machen Sie sich generell bei der Verwendung einer Komponente, die ein Kontingent akzeptiert, mit dessen Auswirkung auf die Sicherheit vertraut, und legen Sie einen sicheren Wert dafür fest.In general, when using any component that accepts a quota, understand its security implications and set it to a safe value.

Siehe auchSee Also

DataContractSerializer
XmlDictionaryReader
XmlSerializer
Bekannte Typen in DatenverträgenData Contract Known Types