CVE-2020-27996 (published 2020-10-29T18:15Z)

An issue was discovered in SmartStoreNET before 4.0.1. It does not properly consider the need for a CustomModelPartAttribute decoration in certain ModelBase.CustomProperties situations.

Severity: MEDIUM
CVSS v2 base score: 6.5 (AV:N/AC:L/Au:S/C:P/I:P/A:P)
CVSS v3 base score: 8.8, HIGH (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/smartstore/SmartStoreNET
commit_details: repo_url: https://github.com/smartstore/SmartStoreNET
author: Murat Cakir
author_date: 2020-08-26 02:02:42+02:00
msg: For security reasons complex types transported via in 'ModelBase.CustomProperties' must be decorated with 'CustomModelPartAttribute' now.
repository: repo_url: https://github.com/smartstore/SmartStoreNET
repo_name: smartstore/SmartStoreNET
description: Open Source ASP.NET MVC Enterprise eCommerce Shopping Cart Solution
repo_language: C#
owner: smartstore
file_changes: filename: BackendExtensionModel.cs
change_type: ModificationType.MODIFY
diff: @@ -2,10 +2,10 @@
 
 namespace SmartStore.DevTools.Models
 {
+	[CustomModelPart]
 	public class BackendExtensionModel : ModelBase
 	{
 		public string Welcome { get; set; }
-
         public int ProductId { get; set; }
     }
 }
\ No newline at end of file

programming_language: C#
filename: FeedGoogleMerchantCenterModel.cs
change_type: ModificationType.MODIFY
diff: @@ -19,6 +19,7 @@ namespace SmartStore.GoogleMerchantCenter.Models
 		public string SearchIsTouched { get; set; }
 	}
 
+	[CustomModelPart]
 	public class GoogleProductModel : ModelBase
 	{
 		public int TotalCount { get; set; }

programming_language: C#
filename: ModelBase.cs
change_type: ModificationType.MODIFY
diff: @@ -6,7 +6,12 @@ using SmartStore.Core.Infrastructure;
 
 namespace SmartStore.Web.Framework.Modelling
 {
-    [Serializable]
+    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
+	public sealed class CustomModelPartAttribute : Attribute
+    {
+    }
+	
+	[Serializable]
 	public sealed class CustomPropertiesDictionary : Dictionary<string, object>
 	{
 	}
@@ -41,9 +46,8 @@ namespace SmartStore.Web.Framework.Modelling
 			Guard.NotEmpty(key, nameof(key));
 
 			IDictionary<string, object> dict;
-			object value;
 
-			if (TryGetCustomThreadProperties(false, out dict) && dict.TryGetValue(key, out value))
+			if (TryGetCustomThreadProperties(false, out dict) && dict.TryGetValue(key, out var value))
 			{
 				return (TProperty)value;
 			}

programming_language: C#
filename: SmartModelBinder.cs
change_type: ModificationType.MODIFY
diff: @@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Linq;
+using System.Security;
 using System.Web.Mvc;
 using SmartStore.Core.Html;
 using SmartStore.Web.Framework.Security;
@@ -82,6 +83,13 @@ namespace SmartStore.Web.Framework.Modelling
 					// Is Complex type
 					var modelName = key.Substring(0, key.Length - subPropertyName.Length - 1);
 					var valueType = GetValueType(keys, modelName, bindingContext.ValueProvider);
+					if (!valueType.HasAttribute<CustomModelPartAttribute>(false))
+                    {
+						throw new SecurityException("For security reasons complex types in '{0}' must be decorated with the '{1}' attribute.".FormatInvariant(
+							typeof(CustomPropertiesDictionary).AssemblyQualifiedNameWithoutVersion(), 
+							typeof(CustomModelPartAttribute).AssemblyQualifiedNameWithoutVersion()));
+                    }
+
 					valueBinder = this.Binders.GetBinder(valueType);
 					var complexBindingContext = new ModelBindingContext
 					{

programming_language: C#