Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Vorsicht
BinaryFormatter Support wird nicht empfohlen. Verwenden Sie sie nur als temporäre Migrationsbrücke für Ältere Anwendungen, die nicht sofort zu den neuen typsicheren APIs migrieren können. Dieser Ansatz birgt erhebliche Sicherheitsrisiken.
In diesem Artikel wird beschrieben, wie Sie eingeschränkte BinaryFormatter Unterstützung für Windows Forms-Zwischenablagevorgänge in .NET 10 konfigurieren. Für Legacyanwendungen, die Zeit für die Migration benötigen, stellen Sie eingeschränkte Funktionalität durch explizite Konfiguration wieder her, da BinaryFormatter in der Laufzeit von .NET 9 aufgrund von Sicherheitsrisiken entfernt wurde.
Vollständige Migrationsanleitungen zu den neuen typsicheren APIs finden Sie unter Windows Forms-Zwischenablage und DataObject-Änderungen in .NET 10.
Von Bedeutung
Dieser Inhalt gilt nur für moderne .NET und nicht für .NET Framework, sofern nicht anders angegeben.
Voraussetzungen
Bevor Sie fortfahren, überprüfen Sie diese Konzepte:
- Wie Ihre Anwendung
BinaryFormatterderzeit in Vorgängen mit der Zwischenablage verwendet. - Die Sicherheitslücken, die zur Entfernung von
BinaryFormatterführten. - Ihre Migrationszeitachse zu den neuen typsicheren Zwischenablage-APIs.
Weitere Informationen finden Sie in den folgenden Artikeln:
- Deserialisierungsrisiken bei Verwendung von BinaryFormatter und verwandten Typen
- BinaryFormatter-Migrationshandbuch
Sicherheitswarnungen und Risiken
BinaryFormatter ist aus folgenden Gründen unsicher und veraltet:
- Sicherheitsanfälligkeiten bezüglich beliebiger Codeausführung: Angreifer können während der Deserialisierung bösartigen Code ausführen und Ihre Anwendung Remoteangriffen offenlegen.
- Denial of Service-Angriffe: Böswillige Zwischenablagedaten können übermäßigen Arbeitsspeicher oder CPU-Ressourcen verbrauchen, was Abstürze oder Instabilität verursacht.
- Informationsveröffentlichungsrisiken: Angreifer extrahieren möglicherweise vertrauliche Daten aus dem Arbeitsspeicher.
- Keine Sicherheitsgrenzen: Das Format ist grundsätzlich unsicher, und Konfigurationseinstellungen können es nicht schützen.
Aktivieren Sie diese Unterstützung nur als temporäre Brücke, während Sie Ihre Anwendung so aktualisieren, dass sie die neuen typsicheren APIs verwendet.
Installieren des Kompatibilitätspakets
Fügen Sie dem Projekt das nicht unterstützte BinaryFormatter Kompatibilitätspaket hinzu. Dieses Paket bietet die erforderliche Laufzeitunterstützung für BinaryFormatter Vorgänge:
<ItemGroup>
<PackageReference Include="System.Runtime.Serialization.Formatters" Version="10.0.0*-*"/>
</ItemGroup>
Hinweis
Dieses Paket ist als nicht unterstützt und veraltet gekennzeichnet. Verwenden Sie sie nur für temporäre Kompatibilität während der Migration.
Unsichere Serialisierung in Ihrem Projekt aktivieren
Legen Sie die EnableUnsafeBinaryFormatterSerialization-Eigenschaft auf true in der Projektdatei fest. Diese Eigenschaft weist den Compiler an, die Verwendung von BinaryFormatter zuzulassen:
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>
Ohne diese Einstellung generiert Ihre Anwendung Kompilierungsfehler, wenn sie versucht, APIs zu verwenden BinaryFormatter .
Konfigurieren der Windows Forms-Laufzeitoption
Erstellen oder aktualisieren Sie die Datei Ihrer Anwendung runtimeconfig.json , um den Windows Forms-spezifischen Zwischenablageschalter zu aktivieren. Mit dieser Konfiguration können Zwischenablageoperationen bei Notwendigkeit auf BinaryFormatter zurückgreifen.
{
"runtimeOptions": {
"configProperties": {
"Windows.ClipboardDragDrop.EnableUnsafeBinaryFormatterSerialization": true
}
}
}
Von Bedeutung
Ohne diesen spezifischen Laufzeitschalter greifen Zwischenablagevorgänge nicht auf BinaryFormatter zurück, selbst wenn die allgemeine Serialisierungsunterstützung aktiviert ist. Dieser Switch ist speziell für die Zwischenablage-Funktionalität von Windows Forms und WPF erforderlich.
Implementierung von sicherheitsorientierten Typenauflösungen
Implementieren Sie auch, wenn BinaryFormatter aktiviert ist, Typen-Resolver, um die Deserialisierung auf explizit genehmigte Typen zu beschränken. Typlöser bieten Ihre einzige Verteidigung gegen böswillige Payload-Angriffe.
Erstellung eines sicheren Typauflösers
// Create a security-focused type resolver
private static Type SecureTypeResolver(TypeName typeName)
{
// Explicit allow-list of permitted types—add only what you need
var allowedTypes = new Dictionary<string, Type>
{
["MyApp.Person"] = typeof(Person),
["MyApp.AppSettings"] = typeof(AppSettings),
["System.String"] = typeof(string),
["System.Int32"] = typeof(int),
// Add only the specific types your application requires
};
// Only allow explicitly listed types - exact string match required
if (allowedTypes.TryGetValue(typeName.FullName, out Type allowedType))
{
return allowedType;
}
// Reject any type not in the allow-list with clear error message
throw new InvalidOperationException(
$"Type '{typeName.FullName}' is not permitted for clipboard deserialization");
}
' Create a security-focused type resolver
Private Shared Function SecureTypeResolver(typeName As TypeName) As Type
' Explicit allow-list of permitted types—add only what you need
Dim allowedTypes As New Dictionary(Of String, Type) From {
{"MyApp.Person", GetType(Person)},
{"MyApp.AppSettings", GetType(AppSettings)},
{"System.String", GetType(String)},
{"System.Int32", GetType(Integer)}
} ' Add only the specific types your application requires
' Only allow explicitly listed types - exact string match required
Dim allowedType As Type = Nothing
If allowedTypes.TryGetValue(typeName.FullName, allowedType) Then
Return allowedType
End If
' Reject any type not in the allow-list with clear error message
Throw New InvalidOperationException(
$"Type '{typeName.FullName}' is not permitted for clipboard deserialization")
End Function
Verwenden Sie den Typlöser mit Zwischenablagevorgängen
// Use the resolver with clipboard operations
private static Type SecureTypeResolver(TypeName typeName)
{
// Implementation from SecureTypeResolver example
// ... (allow-list implementation here)
throw new InvalidOperationException($"Type '{typeName.FullName}' is not permitted");
}
public static void UseSecureTypeResolver()
{
// Retrieve legacy data using the secure type resolver
if (Clipboard.TryGetData("LegacyData", SecureTypeResolver, out MyCustomType data))
{
ProcessLegacyData(data);
}
else
{
Console.WriteLine("No compatible data found on clipboard");
}
}
' Use the resolver with clipboard operations
Private Shared Function SecureTypeResolver(typeName As TypeName) As Type
' Implementation from SecureTypeResolver example
' ... (allow-list implementation here)
Throw New InvalidOperationException($"Type '{typeName.FullName}' is not permitted")
End Function
Public Shared Sub UseSecureTypeResolver()
' Retrieve legacy data using the secure type resolver
Dim data As MyCustomType = Nothing
If Clipboard.TryGetData("LegacyData", AddressOf SecureTypeResolver, data) Then
ProcessLegacyData(data)
Else
Console.WriteLine("No compatible data found on clipboard")
End If
End Sub
Sicherheitsrichtlinien für Typenlöser
Befolgen Sie beim Implementieren von Typlösern die folgenden grundlegenden Sicherheitsrichtlinien:
Explizite Zulassungslisten verwenden
- Standardmäßig ablehnen: Nur explizit aufgelistete Typen zulassen.
- Keine Wildcards: Musterabgleich oder namespacebasierte Berechtigungen vermeiden.
- Exakter Abgleich: Erfordert genaue Zeichenfolgenvergleiche für Typnamen.
Überprüfen aller Eingaben
- Typnamenüberprüfung: Stellen Sie sicher, dass Typnamen den erwarteten Formaten entsprechen.
- Assemblyeinschränkungen: Beschränken Sie Typen auf bekannte, vertrauenswürdige Assemblys.
- Versionsüberprüfung: Berücksichtigen Sie versionsspezifische Typeinschränkungen.
Sicheres Behandeln unbekannter Typen
- Auslösen von Ausnahmen: Wird immer für nicht autorisierte Typen ausgelöst.
- Protokollversuche: Erwägen Sie die Protokollierung nicht autorisierter Zugriffsversuche.
- Löschen von Fehlermeldungen: Geben Sie spezifische Ablehnungsgründe für das Debuggen an.
Regelmäßige Wartung
- Regelmäßig überwachen: Überprüfen und aktualisieren Sie die Liste zulässiger Typen.
- Nicht verwendete Typen entfernen: Entfernen Sie Berechtigungen für Typen, die nicht mehr benötigt werden.
- Dokumententscheidungen: Bewahren Sie eine klare Dokumentation auf, warum jeder Typ zulässig ist.
Testen der Konfiguration
Testen Sie nach dem Konfigurieren BinaryFormatter der Unterstützung Ihre Anwendung, um sicherzustellen, dass sie ordnungsgemäß funktioniert:
- Überprüfen Sie Zwischenablagevorgänge: Testen Sie sowohl das Speichern als auch das Abrufen von Daten mit Ihren benutzerdefinierten Typen.
- Testtyplöser: Vergewissern Sie sich, dass nicht autorisierte Typen ordnungsgemäß abgelehnt werden.
- Sicherheit überwachen: Beobachten Sie unerwartete Typenauflösungsversuche.
- Leistungstests: Stellen Sie sicher, dass der Typlöser die Leistung nicht erheblich beeinträchtigt.
public static void TestBinaryFormatterConfiguration()
{
// Test data to verify configuration
var testPerson = new Person { Name = "Test User", Age = 30 };
try
{
// Test storing data (this should work with proper configuration)
Clipboard.SetData("TestPerson", testPerson);
Console.WriteLine("Successfully stored test data on clipboard");
// Test retrieving with type resolver
if (Clipboard.TryGetData("TestPerson", SecureTypeResolver, out Person retrievedPerson))
{
Console.WriteLine($"Successfully retrieved: {retrievedPerson.Name}, Age: {retrievedPerson.Age}");
}
else
{
Console.WriteLine("Failed to retrieve test data");
}
// Test that unauthorized types are rejected
try
{
Clipboard.TryGetData("TestPerson", UnauthorizedTypeResolver, out Person _);
Console.WriteLine("ERROR: Unauthorized type was not rejected!");
}
catch (InvalidOperationException ex)
{
Console.WriteLine($"SUCCESS: Unauthorized type properly rejected - {ex.Message}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Configuration test failed: {ex.Message}");
}
}
private static Type SecureTypeResolver(TypeName typeName)
{
var allowedTypes = new Dictionary<string, Type>
{
["ClipboardExamples.Person"] = typeof(Person),
};
if (allowedTypes.TryGetValue(typeName.FullName, out Type allowedType))
{
return allowedType;
}
throw new InvalidOperationException($"Type '{typeName.FullName}' is not permitted");
}
private static Type UnauthorizedTypeResolver(TypeName typeName)
{
// Intentionally restrictive resolver to test rejection
throw new InvalidOperationException($"No types are permitted by this test resolver");
}
Public Shared Sub TestBinaryFormatterConfiguration()
' Test data to verify configuration
Dim testPerson As New Person With {.Name = "Test User", .Age = 30}
Try
' Test storing data (this should work with proper configuration)
Clipboard.SetData("TestPerson", testPerson)
Console.WriteLine("Successfully stored test data on clipboard")
' Test retrieving with type resolver
Dim retrievedPerson As Person = Nothing
If Clipboard.TryGetData("TestPerson", AddressOf SecureTypeResolver, retrievedPerson) Then
Console.WriteLine($"Successfully retrieved: {retrievedPerson.Name}, Age: {retrievedPerson.Age}")
Else
Console.WriteLine("Failed to retrieve test data")
End If
' Test that unauthorized types are rejected
Try
Dim testResult As Person = Nothing
Clipboard.TryGetData("TestPerson", AddressOf UnauthorizedTypeResolver, testResult)
Console.WriteLine("ERROR: Unauthorized type was not rejected!")
Catch ex As InvalidOperationException
Console.WriteLine($"SUCCESS: Unauthorized type properly rejected - {ex.Message}")
End Try
Catch ex As Exception
Console.WriteLine($"Configuration test failed: {ex.Message}")
End Try
End Sub
Private Shared Function SecureTypeResolver(typeName As TypeName) As Type
Dim allowedTypes As New Dictionary(Of String, Type) From {
{"ClipboardExamples.Person", GetType(Person)}
}
Dim allowedType As Type = Nothing
If allowedTypes.TryGetValue(typeName.FullName, allowedType) Then
Return allowedType
End If
Throw New InvalidOperationException($"Type '{typeName.FullName}' is not permitted")
End Function
Private Shared Function UnauthorizedTypeResolver(typeName As TypeName) As Type
' Intentionally restrictive resolver to test rejection
Throw New InvalidOperationException($"No types are permitted by this test resolver")
End Function
Planen Ihrer Migrationsstrategie
Während BinaryFormatter die Unterstützung temporäre Kompatibilität bietet, entwickeln Sie einen Migrationsplan, um zu den neuen typsicheren APIs zu wechseln:
- Verwendung identifizieren: Katalogisieren Sie alle Zwischenablagevorgänge mit benutzerdefinierten Typen.
- Priorisieren Sie die Migration: Konzentrieren Sie sich zuerst auf die sicherheitsempfindlichsten Vorgänge.
- Inkrementell aktualisieren: Migrieren Sie jeweils einen Vorgang, um das Risiko zu reduzieren.
- Testen Sie sorgfältig: Stellen Sie sicher, dass neue Implementierungen gleichwertige Funktionen bieten.
- BinaryFormatter entfernen: Deaktivieren Sie die Unterstützung, sobald die Migration abgeschlossen ist.
Bereinigen von Ressourcen
Nachdem Sie zu den neuen typsicheren Zwischenablage-APIs migriert haben, entfernen Sie die BinaryFormatter Konfiguration, um die Sicherheit zu verbessern.
- Entfernen Sie den
System.Runtime.Serialization.FormattersPaketverweis. - Entfernen Sie die
EnableUnsafeBinaryFormatterSerializationEigenschaft aus der Projektdatei. - Entfernen Sie die
Windows.ClipboardDragDrop.EnableUnsafeBinaryFormatterSerializationEinstellung von Ihremruntimeconfig.json. - Löschen Sie Implementierungen des Typlösers, die nicht mehr benötigt werden.
Verwandte Inhalte
.NET Desktop feedback