Added ImageEffectsSerializationBinder to improve security of JSON deserialization

This commit is contained in:
Jaex 2021-05-31 09:32:50 +03:00
parent caba14a36e
commit f32da61fab
7 changed files with 19 additions and 28 deletions

View file

@ -157,11 +157,7 @@ private object Deserialize(string json)
JsonSerializer serializer = new JsonSerializer();
serializer.Converters.Add(new StringEnumConverter());
serializer.ObjectCreationHandling = ObjectCreationHandling.Replace;
serializer.TypeNameHandling = TypeNameHandling.Auto;
if (SerializationBinder != null)
{
serializer.SerializationBinder = SerializationBinder;
}
if (SerializationBinder != null) serializer.SerializationBinder = SerializationBinder;
serializer.Error += (sender, e) => e.ErrorContext.Handled = true;
return serializer.Deserialize(textReader, ObjectType);
}

View file

@ -1360,6 +1360,13 @@ public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
return instances.ToArray();
}
public static IEnumerable<Type> FindSubclassesOf<TBaseType>()
{
Type baseType = typeof(TBaseType);
Assembly assembly = baseType.Assembly;
return assembly.GetTypes().Where(t => t.IsSubclassOf(baseType));
}
public static string GetOperatingSystemProductName(bool includeBit = false)
{
string productName = null;

View file

@ -47,7 +47,6 @@ public static class JsonHelpers
serializer.Converters.Add(new StringEnumConverter());
serializer.DefaultValueHandling = defaultValueHandling;
serializer.NullValueHandling = nullValueHandling;
serializer.TypeNameHandling = TypeNameHandling.Auto;
if (serializationBinder != null) serializer.SerializationBinder = serializationBinder;
serializer.Serialize(jsonTextWriter, obj);
}
@ -110,7 +109,6 @@ public static T Deserialize<T>(TextReader textReader, ISerializationBinder seria
JsonSerializer serializer = new JsonSerializer();
serializer.Converters.Add(new StringEnumConverter());
serializer.ObjectCreationHandling = ObjectCreationHandling.Replace;
serializer.TypeNameHandling = TypeNameHandling.Auto;
if (serializationBinder != null) serializer.SerializationBinder = serializationBinder;
serializer.Error += (sender, e) => e.ErrorContext.Handled = true;
return serializer.Deserialize<T>(jsonTextReader);

View file

@ -297,7 +297,6 @@
<Compile Include="ShareXTheme.cs" />
<Compile Include="TextBoxTraceListener.cs" />
<Compile Include="Settings\SafeStringEnumConverter.cs" />
<Compile Include="Settings\TypeNameSerializationBinder.cs" />
<Compile Include="UITypeEditors\EnumDescriptionConverter.cs" />
<Compile Include="UITypeEditors\DirectoryNameEditor.cs" />
<Compile Include="UITypeEditors\EnumProperNameKeepCaseConverter.cs" />

View file

@ -50,7 +50,7 @@ public partial class ImageEffectsForm : Form
public string FilePath { get; private set; }
private bool pauseUpdate;
private ISerializationBinder serializationBinder = new TypeNameSerializationBinder("ShareX.ImageEffectsLib", "ShareX.ImageEffectsLib");
private ISerializationBinder serializationBinder = new ImageEffectsSerializationBinder();
public ImageEffectsForm(Bitmap bmp, List<ImageEffectPreset> presets, int selectedPresetIndex)
{

View file

@ -24,19 +24,20 @@
#endregion License Information (GPL v3)
using Newtonsoft.Json.Serialization;
using ShareX.HelpersLib;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ShareX.HelpersLib
namespace ShareX.ImageEffectsLib
{
public class TypeNameSerializationBinder : ISerializationBinder
public class ImageEffectsSerializationBinder : ISerializationBinder
{
public string AppNamespace { get; private set; }
public string AppAssembly { get; private set; }
public IEnumerable<Type> KnownTypes { get; set; }
public TypeNameSerializationBinder(string appNamespace, string appAssembly)
public ImageEffectsSerializationBinder()
{
AppNamespace = appNamespace;
AppAssembly = appAssembly;
KnownTypes = Helpers.FindSubclassesOf<ImageEffect>();
}
public void BindToName(Type serializedType, out string assemblyName, out string typeName)
@ -47,18 +48,7 @@ public void BindToName(Type serializedType, out string assemblyName, out string
public Type BindToType(string assemblyName, string typeName)
{
string resolvedTypeName;
if (!string.IsNullOrEmpty(assemblyName))
{
resolvedTypeName = $"{typeName}, {assemblyName}";
}
else
{
resolvedTypeName = $"{AppNamespace}.{typeName}, {AppAssembly}";
}
return Type.GetType(resolvedTypeName, true);
return KnownTypes.SingleOrDefault(t => t.Name == typeName);
}
}
}

View file

@ -171,6 +171,7 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="ImageEffectsSerializationBinder.cs" />
<Compile Include="WatermarkConfig.cs" />
</ItemGroup>
<ItemGroup>