Skip to content

Commit

Permalink
added check for custom type deserialization
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Schwarz authored and Michael Schwarz committed Nov 29, 2021
1 parent 1b74b05 commit 58b6571
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 33 deletions.
6 changes: 2 additions & 4 deletions AjaxPro/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
* MR Matthew Raymer
*
*
*
*
* MS 06-04-03 fixed missing http error status code in core.js
* MS 06-04-04 added AjaxPro.onError, onTimeout, onStateChanged, onLoading to core.js
* MS 06-04-05 removed Object.prototype.extend from prototype.js and all othere files using this
Expand All @@ -41,7 +39,7 @@
* MS 06-07-19 removed ReflectionPermission attribute (why did we add it?)
* MS 21-10-30 added contentSecurityPolicy to specify a nonce for all scripts
* MS 21-11-22 changed default behavior of passing types during deserialization to deny
*
* MS 21-11-29 added check for custom type deserialization
*
*/
using System;
Expand Down Expand Up @@ -93,7 +91,7 @@
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:

[assembly: AssemblyVersion("21.11.22.1")] // do not remove the blanks!!!!
[assembly: AssemblyVersion("21.11.29.1")] // do not remove the blanks!!!!

//
// In order to sign your assembly you must specify a key to use. Refer to the
Expand Down
5 changes: 4 additions & 1 deletion AjaxPro/JSON/Converters/DataTableConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
* MS 06-09-26 improved performance using StringBuilder
* MS 07-04-24 added renderJsonCompliant serialization
* MS 08-03-21 fixed DataTable client-side script
*
* MS 21-11-29 added check for custom type deserialization
*
*
*/
Expand Down Expand Up @@ -147,7 +147,10 @@ public override object Deserialize(IJavaScriptObject o, Type t)
for (int i = 0; i < columns.Count; i++)
{
column = (JavaScriptArray)columns[i];

colType = Type.GetType(column[1].ToString(), true);
JavaScriptDeserializer.ThrowExceptionIfNotCustomTypeDeserializationAllowed(colType);

dt.Columns.Add(column[0].ToString(), colType);
}

Expand Down
13 changes: 10 additions & 3 deletions AjaxPro/JSON/Converters/HashtableConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
* MS 06-09-24 use QuoteString instead of Serialize
* MS 06-09-26 improved performance using StringBuilder
* MS 07-04-24 added renderJsonCompliant serialization
*
* MS 21-11-29 added check for custom type deserialization
*
*/
using System;
Expand Down Expand Up @@ -86,8 +86,15 @@ public override object Deserialize(IJavaScriptObject o, Type t)
for (int i = 0; i < a.Count; i++)
{
aa = (JavaScriptArray)a[i];
key = JavaScriptDeserializer.Deserialize((IJavaScriptObject)aa[0], Type.GetType(((JavaScriptString)aa[2]).ToString()));
value = JavaScriptDeserializer.Deserialize((IJavaScriptObject)aa[1], Type.GetType(((JavaScriptString)aa[3]).ToString()));

Type keyType = Type.GetType(((JavaScriptString)aa[2]).ToString());
Type valueType = Type.GetType(((JavaScriptString)aa[3]).ToString());

JavaScriptDeserializer.ThrowExceptionIfNotCustomTypeDeserializationAllowed(keyType);
JavaScriptDeserializer.ThrowExceptionIfNotCustomTypeDeserializationAllowed(valueType);

key = JavaScriptDeserializer.Deserialize((IJavaScriptObject)aa[0], keyType);
value = JavaScriptDeserializer.Deserialize((IJavaScriptObject)aa[1], valueType);

d.Add(key, value);
}
Expand Down
6 changes: 5 additions & 1 deletion AjaxPro/JSON/Converters/HtmlControlConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
/*
* MS 06-05-23 using local variables instead of "new Type()" for get De-/SerializableTypes
* MS 06-09-26 improved performance using StringBuilder
* MS 21-11-29 added check for custom type deserialization
*
*
*
*/
Expand Down Expand Up @@ -171,12 +173,14 @@ internal static HtmlControl HtmlControlFromString(string html, Type type)
if(!typeof(HtmlControl).IsAssignableFrom(type))
throw new InvalidCastException("The target type is not a HtmlControlType");

JavaScriptDeserializer.ThrowExceptionIfNotCustomTypeDeserializationAllowed(type);

html = AddRunAtServer(html, (Activator.CreateInstance(type) as HtmlControl).TagName);

if(type.IsAssignableFrom(typeof(HtmlSelect)))
html = CorrectAttributes(html);

Control o = HtmlControlConverterHelper.Parse(html);;
Control o = HtmlControlConverterHelper.Parse(html);

if(o.GetType() == type)
return (o as HtmlControl);
Expand Down
70 changes: 48 additions & 22 deletions AjaxPro/JSON/JavaScriptDeserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@
* MS 06-09-26 improved performance removing three-times cast
* MS 21-10-27 added allowed customized types for JSON deserialization
* MS 21-11-22 changed error message when type is not allowed
*
* MS 21-11-29 added check for custom type deserialization
*
*/
using System;
using System.Text;
using System.Reflection;
using System.Collections;
using System.Security;

namespace AjaxPro
{
Expand Down Expand Up @@ -146,27 +147,7 @@ public static object Deserialize(IJavaScriptObject o, Type type)
if (type == null || type.IsAssignableFrom(t))
{
type = t;

if (AjaxPro.Utility.Settings.IsCustomTypesDeserializationDisabled)
{
bool isCustomTypeAllowed = false;

foreach (var s in AjaxPro.Utility.Settings.JsonDeserializationCustomTypesAllowed)
if ((s.EndsWith("*") && type.FullName.StartsWith(s.Substring(0, s.Length - 1), StringComparison.InvariantCultureIgnoreCase)) || s == type.FullName)
{
isCustomTypeAllowed = true;
break;
}

if (!isCustomTypeAllowed)
throw new System.Security.SecurityException("This type is not allowed as argument for this method.");
}
else
{
foreach (var s in AjaxPro.Utility.Settings.JsonDeserializationCustomTypesDenied)
if ((s.EndsWith("*") && type.FullName.StartsWith(s.Substring(0, s.Length -1), StringComparison.InvariantCultureIgnoreCase)) || s == type.FullName)
throw new System.Security.SecurityException("This type is not allowed as argument for this method.");
}
ThrowExceptionIfNotCustomTypeDeserializationAllowed(type);
}
}

Expand Down Expand Up @@ -228,6 +209,51 @@ public static object Deserialize(IJavaScriptObject o, Type type)

#region Internal Methods

internal static void ThrowExceptionIfNotCustomTypeDeserializationAllowed(Type type)
{
SecurityException ex = null;
if (!IsCustomTypeDeserializationAllowed(type, out ex) && ex != null)
throw ex;
}

internal static bool IsCustomTypeDeserializationAllowed(Type type, out SecurityException ex)
{
ex = null;

// allow all primitive and basic types
if (type.IsPrimitive || type == typeof(string) || type == typeof(DateTime) || type == typeof(TimeSpan) || type == typeof(decimal))
return true;

if (AjaxPro.Utility.Settings.IsCustomTypesDeserializationDisabled)
{
bool isCustomTypeAllowed = false;

foreach (var s in AjaxPro.Utility.Settings.JsonDeserializationCustomTypesAllowed)
if ((s.EndsWith("*") && type.FullName.StartsWith(s.Substring(0, s.Length - 1), StringComparison.InvariantCultureIgnoreCase)) || s == type.FullName)
{
isCustomTypeAllowed = true;
break;
}

if (!isCustomTypeAllowed)
{
ex = new SecurityException("This type is not allowed as argument for this method.");
return false;
}
}
else
{
foreach (var s in AjaxPro.Utility.Settings.JsonDeserializationCustomTypesDenied)
if ((s.EndsWith("*") && type.FullName.StartsWith(s.Substring(0, s.Length - 1), StringComparison.InvariantCultureIgnoreCase)) || s == type.FullName)
{
ex = new SecurityException("This type is not allowed as argument for this method.");
return false;
}
}

return true;
}

/// <summary>
/// Deserializes the custom object.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions AjaxPro/Utilities/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
* using new AjaxSecurityProvider
* MS 09-02-17 fixed memory problem
* MS 21-10-30 added contentSecurityPolicy to specify a nonce for all scripts
*
* MS 21-11-29 removed HtmlControlConverter from default converters
*
*/
using System;
Expand Down Expand Up @@ -254,7 +254,7 @@ internal static void AddDefaultConverter(AjaxSettings settings)
AddConverter(settings, new IEnumerableConverter());

AddConverter(settings, new DataRowConverter());
AddConverter(settings, new HtmlControlConverter());
//AddConverter(settings, new HtmlControlConverter());

#endregion
}
Expand Down

0 comments on commit 58b6571

Please sign in to comment.