CVE-2022-23535: Deserialization of Untrusted Data (CWE-502)
value: LiteDB is a small, fast and lightweight .NET NoSQL embedded database. Versions prior to 5.0.13 are subject to Deserialization of Untrusted Data. LiteDB uses a special field in JSON documents to cast different types from `BsonDocument` to POCO classes. When instances of an object are not the same of class, `BsonMapper` use a special field `_type` string info with full class name with assembly to be loaded and fit into your model. If your end-user can send to your app a plain JSON string, deserialization can load an unsafe  object to fit into your model. This issue is patched in version 5.0.13 with some basic fixes to avoid this, but is not 100% guaranteed when using `Object` type. The next major version will contain an allow-list to select what kind of Assembly can be loaded. Workarounds are detailed in the vendor advisory.
CWE description: The product deserializes untrusted data without sufficiently verifying that the resulting data will be valid.
CVSS v3 base score: 9.8
Published: 2023-02-24T23:15Z
Repository: https://github.com/mbdavid/LiteDB
Language: C#
Files changed: LiteDB.sln, LiteDB/Client/Mapper/BsonMapper.Deserialize.cs, LiteDB/LiteDB.csproj, LiteDB/Utils/LiteException.cs
Commit date: 2022-12-08 12:03:28 -0300
Commit message: Adding testing for Process object deserializaion rule

Diff: diff --git a/LiteDB.sln b/LiteDB.sln
index 1d02cb64..848dbb66 100644
--- a/LiteDB.sln
+++ b/LiteDB.sln
@@ -1,9 +1,9 @@
 ﻿
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29609.76
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32328.378
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LiteDB", "LiteDB\LiteDB.csproj", "{9497DA19-1FCA-4C2E-A1AB-8DFAACBC76E1}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LiteDB.Tests", "LiteDB.Tests\LiteDB.Tests.csproj", "{74E32E43-2A57-4A38-BD8C-9108B0DCAEAA}"
 EndProject
diff --git a/LiteDB/Client/Mapper/BsonMapper.Deserialize.cs b/LiteDB/Client/Mapper/BsonMapper.Deserialize.cs
index 5660db62..f347ae52 100644
--- a/LiteDB/Client/Mapper/BsonMapper.Deserialize.cs
+++ b/LiteDB/Client/Mapper/BsonMapper.Deserialize.cs
@@ -168,11 +168,24 @@ namespace LiteDB
                 if (doc.TryGetValue("_type", out var typeField) && typeField.IsString)
                 {
                     var actualType = _typeNameBinder.GetType(typeField.AsString);
 
                     if (actualType == null) throw LiteException.InvalidTypedName(typeField.AsString);
-                    if (!type.IsAssignableFrom(actualType)) throw LiteException.DataTypeNotAssignable(type.FullName, actualType.FullName);
+
+                    // avoid initialize class that are not assignable 
+                    if (!type.IsAssignableFrom(actualType))
+                    {
+                        throw LiteException.DataTypeNotAssignable(type.FullName, actualType.FullName);
+                    }
+
+                    // avoid use of "System.Diagnostics.Process" in object type definition
+                    // using String test to work in .netstandard 1.3
+                    if (actualType.FullName.Equals("System.Diagnostics.Process", StringComparison.OrdinalIgnoreCase) &&
+                        actualType.Assembly.GetName().Name.Equals("System", StringComparison.OrdinalIgnoreCase))
+                    {
+                        throw LiteException.AvoidUseOfProcess();
+                    }
 
                     type = actualType;
                 }
                 // when complex type has no definition (== typeof(object)) use Dictionary<string, object> to better set values
                 else if (type == typeof(object))
diff --git a/LiteDB/LiteDB.csproj b/LiteDB/LiteDB.csproj
index cbc9b044..58865570 100644
--- a/LiteDB/LiteDB.csproj
+++ b/LiteDB/LiteDB.csproj
@@ -1,9 +1,9 @@
 ﻿<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFrameworks>net45;netstandard1.3;netstandard2.0</TargetFrameworks>
+    <TargetFrameworks>net4.5;netstandard1.3;netstandard2.0</TargetFrameworks>
     <AssemblyVersion>5.0.12</AssemblyVersion>
     <FileVersion>5.0.12</FileVersion>
     <VersionPrefix>5.0.12</VersionPrefix>
     <Authors>Maurício David</Authors>
     <Product>LiteDB</Product>
diff --git a/LiteDB/Utils/LiteException.cs b/LiteDB/Utils/LiteException.cs
index a27dc3c8..2a123104 100644
--- a/LiteDB/Utils/LiteException.cs
+++ b/LiteDB/Utils/LiteException.cs
@@ -50,10 +50,11 @@ namespace LiteDB
         public const int INITIALSIZE_CRYPTO_NOT_SUPPORTED = 210;
         public const int INVALID_INITIALSIZE = 211;
         public const int INVALID_NULL_CHAR_STRING = 212;
         public const int INVALID_FREE_SPACE_PAGE = 213;
         public const int DATA_TYPE_NOT_ASSIGNABLE = 214;
+        public const int AVOID_USE_OF_PROCESS = 215;
 
         #endregion
 
         #region Ctor
 
@@ -310,8 +311,13 @@ namespace LiteDB
         internal static LiteException DataTypeNotAssignable(string type1, string type2)
         {
             return new LiteException(DATA_TYPE_NOT_ASSIGNABLE, $"Data type {type1} is not assignable from data type {type2}");
         }
 
+        internal static LiteException AvoidUseOfProcess()
+        {
+            return new LiteException(AVOID_USE_OF_PROCESS, $"LiteDB do not accept System.Diagnostics.Process class in deserialize mapper");
+        }
+
         #endregion
     }
 }
\ No newline at end of file

Vulnerable code: # Visual Studio Version 16
VisualStudioVersion = 16.0.29609.76
                    if (!type.IsAssignableFrom(actualType)) throw LiteException.DataTypeNotAssignable(type.FullName, actualType.FullName);
    <TargetFrameworks>net45;netstandard1.3;netstandard2.0</TargetFrameworks>
Fixed code: # Visual Studio Version 17
VisualStudioVersion = 17.1.32328.378

                    // avoid initialize class that are not assignable 
                    if (!type.IsAssignableFrom(actualType))
                    {
                        throw LiteException.DataTypeNotAssignable(type.FullName, actualType.FullName);
                    }

                    // avoid use of "System.Diagnostics.Process" in object type definition
                    // using String test to work in .netstandard 1.3
                    if (actualType.FullName.Equals("System.Diagnostics.Process", StringComparison.OrdinalIgnoreCase) &&
                        actualType.Assembly.GetName().Name.Equals("System", StringComparison.OrdinalIgnoreCase))
                    {
                        throw LiteException.AvoidUseOfProcess();
                    }
    <TargetFrameworks>net4.5;netstandard1.3;netstandard2.0</TargetFrameworks>
        public const int AVOID_USE_OF_PROCESS = 215;
        internal static LiteException AvoidUseOfProcess()
        {
            return new LiteException(AVOID_USE_OF_PROCESS, $"LiteDB do not accept System.Diagnostics.Process class in deserialize mapper");
        }