diff --git a/src/libraries/System.Text.Json/src/Resources/Strings.resx b/src/libraries/System.Text.Json/src/Resources/Strings.resx
index 5186d1dc48727c..9e3b8d332f4eb4 100644
--- a/src/libraries/System.Text.Json/src/Resources/Strings.resx
+++ b/src/libraries/System.Text.Json/src/Resources/Strings.resx
@@ -506,4 +506,7 @@
Cannot allocate a buffer of size {0}.
+
+ Serialization and deserialization of 'System.Type' instances are not supported and should be avoided since they can lead to security issues.
+
\ No newline at end of file
diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj
index ee9488ed2c0cb2..94c7b47f1b0c6f 100644
--- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj
+++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj
@@ -109,6 +109,7 @@
+
diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/TypeConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/TypeConverter.cs
new file mode 100644
index 00000000000000..1fae3f3a58ac86
--- /dev/null
+++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/TypeConverter.cs
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Text.Json.Serialization.Converters
+{
+ internal sealed class TypeConverter : JsonConverter
+ {
+ public override Type Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ throw new NotSupportedException(SR.SerializeTypeInstanceNotSupported);
+ }
+
+ public override void Write(Utf8JsonWriter writer, Type value, JsonSerializerOptions options)
+ {
+ throw new NotSupportedException(SR.SerializeTypeInstanceNotSupported);
+ }
+ }
+}
diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs
index 3e884eb49621bc..8a241a13c9fd99 100644
--- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs
+++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs
@@ -37,7 +37,7 @@ public sealed partial class JsonSerializerOptions
private static Dictionary GetDefaultSimpleConverters()
{
- const int NumberOfSimpleConverters = 21;
+ const int NumberOfSimpleConverters = 22;
var converters = new Dictionary(NumberOfSimpleConverters);
// Use a dictionary for simple converters.
@@ -59,6 +59,7 @@ private static Dictionary GetDefaultSimpleConverters()
Add(new SByteConverter());
Add(new SingleConverter());
Add(new StringConverter());
+ Add(new TypeConverter());
Add(new UInt16Converter());
Add(new UInt32Converter());
Add(new UInt64Converter());
diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs
index 6ff469e1616d0d..f43c530a6eeda1 100644
--- a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs
+++ b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs
@@ -28,7 +28,7 @@ public static void ThrowNotSupportedException_SerializationNotSupported(Type pro
[DoesNotReturn]
[MethodImpl(MethodImplOptions.NoInlining)]
- public static NotSupportedException ThrowNotSupportedException_ConstructorMaxOf64Parameters(ConstructorInfo constructorInfo, Type type)
+ public static void ThrowNotSupportedException_ConstructorMaxOf64Parameters(ConstructorInfo constructorInfo, Type type)
{
throw new NotSupportedException(SR.Format(SR.ConstructorMaxOf64Parameters, constructorInfo, type));
}
diff --git a/src/libraries/System.Text.Json/tests/Serialization/ExceptionTests.cs b/src/libraries/System.Text.Json/tests/Serialization/ExceptionTests.cs
index ae5a45b9431383..a9db0e73b64854 100644
--- a/src/libraries/System.Text.Json/tests/Serialization/ExceptionTests.cs
+++ b/src/libraries/System.Text.Json/tests/Serialization/ExceptionTests.cs
@@ -526,5 +526,58 @@ public static void UnsupportedTypeFromRoot()
// Root-level Types (not from a property) do not include the Path.
Assert.DoesNotContain("Path: $", ex.Message);
}
+
+ [Fact]
+ public static void DeserializeTypeInstance()
+ {
+ string json = @"""System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e""";
+
+ NotSupportedException ex = Assert.Throws(() => JsonSerializer.Deserialize(json));
+ string exAsStr = ex.ToString();
+ Assert.Contains("System.Type", exAsStr);
+ Assert.Contains("$", exAsStr);
+
+ json = $@"{{""Type"":{json}}}";
+
+ ex = Assert.Throws(() => JsonSerializer.Deserialize(json));
+ exAsStr = ex.ToString();
+ Assert.Contains("System.Type", exAsStr);
+ Assert.Contains("$.Type", exAsStr);
+
+ // NSE is not thrown because the serializer handles null.
+ Assert.Null(JsonSerializer.Deserialize("null"));
+
+ ClassWithType obj = JsonSerializer.Deserialize(@"{""Type"":null}");
+ Assert.Null(obj.Type);
+ }
+
+ [Fact]
+ public static void SerializeTypeInstance()
+ {
+ Type type = typeof(int);
+
+ NotSupportedException ex = Assert.Throws(() => JsonSerializer.Serialize(type));
+ string exAsStr = ex.ToString();
+ Assert.Contains("System.Type", exAsStr);
+ Assert.Contains("$", exAsStr);
+
+ type = null;
+ string serialized = JsonSerializer.Serialize(type);
+ Assert.Equal("null", serialized);
+
+ ClassWithType obj = new ClassWithType { Type = typeof(int) };
+
+ ex = Assert.Throws(() => JsonSerializer.Serialize(obj));
+ exAsStr = ex.ToString();
+ Assert.Contains("System.Type", exAsStr);
+ Assert.Contains("$.Type", exAsStr);
+
+ obj.Type = null;
+ serialized = JsonSerializer.Serialize(obj);
+ Assert.Equal(@"{""Type"":null}", serialized);
+
+ serialized = JsonSerializer.Serialize(obj, new JsonSerializerOptions { IgnoreNullValues = true });
+ Assert.Equal(@"{}", serialized);
+ }
}
}
diff --git a/src/libraries/System.Text.Json/tests/Serialization/TestClasses.cs b/src/libraries/System.Text.Json/tests/Serialization/TestClasses.cs
index 7d64e125493ea4..9be040589afe29 100644
--- a/src/libraries/System.Text.Json/tests/Serialization/TestClasses.cs
+++ b/src/libraries/System.Text.Json/tests/Serialization/TestClasses.cs
@@ -1853,4 +1853,9 @@ public void Verify()
MyData.Verify();
}
}
+
+ public class ClassWithType
+ {
+ public Type Type { get; set; }
+ }
}