是否可以将Json.Net设置为忽略$ type?

时间:2018-01-08 23:21:50

标签: c# json json.net

观察this video on json deserialization attacks并显示这一点json,可用于在任何反序列化它的应用程序上触发任意代码执行。

Using ObjectDataProvider to execute arbitrary code

现在在我的应用程序中,我甚至从未使用过类型的json。我总是反序列化为动态对象或 UnicodeDecodeError Traceback (most recent call last) <ipython-input-9-6f467123fe04> in <module>() ----> 1 import matplotlib.pyplot C:\Users\Owner\Anaconda2\envs\gl-env\lib\site-packages\matplotlib\pyplot.py in <module>() 27 from cycler import cycler 28 import matplotlib ---> 29 import matplotlib.colorbar 30 from matplotlib import style 31 from matplotlib import _pylab_helpers, interactive C:\Users\Owner\Anaconda2\envs\gl-env\lib\site-packages\matplotlib\colorbar.py in <module>() 32 import matplotlib.artist as martist 33 import matplotlib.cbook as cbook ---> 34 import matplotlib.collections as collections 35 import matplotlib.colors as colors 36 import matplotlib.contour as contour C:\Users\Owner\Anaconda2\envs\gl-env\lib\site-packages\matplotlib\collections.py in <module>() 25 import matplotlib.artist as artist 26 from matplotlib.artist import allow_rasterization ---> 27 import matplotlib.backend_bases as backend_bases 28 import matplotlib.path as mpath 29 from matplotlib import _path C:\Users\Owner\Anaconda2\envs\gl-env\lib\site-packages\matplotlib\backend_bases.py in <module>() 60 61 import matplotlib.tight_bbox as tight_bbox ---> 62 import matplotlib.textpath as textpath 63 from matplotlib.path import Path 64 from matplotlib.cbook import mplDeprecation, warn_deprecated C:\Users\Owner\Anaconda2\envs\gl-env\lib\site-packages\matplotlib\textpath.py in <module>() 13 from matplotlib.path import Path 14 from matplotlib import rcParams ---> 15 import matplotlib.font_manager as font_manager 16 from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_NO_HINTING 17 from matplotlib.ft2font import LOAD_TARGET_LIGHT C:\Users\Owner\Anaconda2\envs\gl-env\lib\site-packages\matplotlib\font_manager.py in <module>() 1419 verbose.report("Using fontManager instance from %s" % _fmcache) 1420 except: -> 1421 _rebuild() 1422 else: 1423 _rebuild() C:\Users\Owner\Anaconda2\envs\gl-env\lib\site-packages\matplotlib\font_manager.py in _rebuild() 1404 def _rebuild(): 1405 global fontManager -> 1406 fontManager = FontManager() 1407 if _fmcache: 1408 pickle_dump(fontManager, _fmcache) C:\Users\Owner\Anaconda2\envs\gl-env\lib\site-packages\matplotlib\font_manager.py in __init__(self, size, weight) 1042 # Load TrueType fonts and create font dictionary. 1043 -> 1044 self.ttffiles = findSystemFonts(paths) + findSystemFonts() 1045 self.defaultFamily = { 1046 'ttf': 'Bitstream Vera Sans', C:\Users\Owner\Anaconda2\envs\gl-env\lib\site-packages\matplotlib\font_manager.py in findSystemFonts(fontpaths, fontext) 311 fontpaths = [fontdir] 312 # now get all installed fonts directly... --> 313 for f in win32InstalledFonts(fontdir): 314 base, ext = os.path.splitext(f) 315 if len(ext)>1 and ext[1:].lower() in fontexts: C:\Users\Owner\Anaconda2\envs\gl-env\lib\site-packages\matplotlib\font_manager.py in win32InstalledFonts(directory, fontext) 228 continue 229 if not os.path.dirname(direc): --> 230 direc = os.path.join(directory, direc) 231 direc = os.path.abspath(direc).lower() 232 if os.path.splitext(direc)[1][1:] in fontext: C:\Users\Owner\Anaconda2\envs\gl-env\lib\ntpath.pyc in join(path, *paths) 83 if result_path and result_path[-1] not in '\\/': 84 result_path = result_path + '\\' ---> 85 result_path = result_path + p_path 86 ## add separator between UNC and non-absolute path 87 if (result_path and result_path[0] not in '\\/' and UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 7: ordinal not in range(128) 。在今天早上另一场无关的谈话之前,我甚至都不知道JObject财产。

我的json设置中是否有一种方法可以告诉它永远不会写或读取此属性?这不是我想要的东西。

2 个答案:

答案 0 :(得分:8)

"$type"信息只有在TypeNameHandling被修改为TypeNameHandling.None以外的其他内容时才会写入 - 这是默认。如果您从未更改过该值,则永远不会发出"$type"信息。

同样"$type"属性在TypeNameHandling = TypeNameHandling.None(同样是默认值)时反序列化时会被忽略,如docs中所述:

// for security TypeNameHandling is required when deserializing
Stockholder newStockholder =
  JsonConvert.DeserializeObject<Stockholder>(jsonTypeNameAuto, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto
});

如果您的代码(或代码使用的类库)中的任何内容都未将TypeNameHandling修改为TypeNameHandling.None以外的内容(通过settingsJsonPropertyAttribute.TypeNameHandling等属性然后,代码执行攻击无法工作。 (有关Json.NET序列化程序使用且不易受此攻击影响的更详细的详细信息,请参阅Alvaro Muñoz & Oleksandr Mirosh's blackhat paper

另请注意,如果您使用JToken.Parse()(或某些类似的静态方法,如JObject.Parse())进行解析而不是使用JsonSerializer.Deserialize<T>()进行反序列化,那么"$type"属性的存在将会只是导致这些属性填充到JToken层次结构中,因为JToken.Parse()从不调用序列化程序。如果您仍希望在解析后删除这些"$type"属性,则可以使用 Deserialize string that was serialized with TypeNameHandling.All 中的JsonExtensions.RemoveTypeMetadata(this JToken root)来执行此操作。

话虽这么说,如果集合由另一个使用TypeNameHandling.ArraysTypeNameHandling.All的应用程序序列化,那么JSON中将有一个额外的嵌套级别。要在反序列化时将其删除,请参阅 Strategies for migrating serialized Json.NET document between versions/formats 中的IgnoreCollectionTypeConverter Make Json.NET ignore $type if it's incompatible 中的IgnoreArrayTypeConverter

最后,如果您正在使用在属性中设置TypeNameHandling的第三方库,则可以使用自定义合约解析程序将其禁用,如 How to disable TypeNameHandling when specified in attributes by using JsonSerializerSettings in Json.NET? 中所示。< / p>

如果您真的担心团队中的其他人可能启用TypeNameHandling,您可以创建一个自定义ISerializationBinder,只要尝试解析类型或类型名称,就会抛出异常:

public class DisallowSerializationBindingBinder : ISerializationBinder
{
 #region ISerializationBinder Members

 public void BindToName(Type serializedType, out string assemblyName, out string typeName)
 {
  throw new JsonSerializationException("Binding of subtypes has been disabled");
 }

 public Type BindToType(string assemblyName, string typeName)
 {
  throw new JsonSerializationException("Binding of subtypes has been disabled");
 }

  #endregion
}

然后在JsonSerializerSettings中设置如下:

var settings = new JsonSerializerSettings
{
    SerializationBinder = new DisallowSerializationBindingBinder(),
};

并全局修改设置,如 Set default global json serializer settings (对于控制台应用), How to set custom JsonSerializerSettings for Json.NET in MVC 4 Web API? (对于ASP.NET Web API)或 JsonSerializerSettings and Asp.Net Core (对于asp.net核心)。

答案 1 :(得分:2)

很遗憾,TypeNameHandling.None被忽略了。但是您可以使用:

public static JsonSerializerSettings JsonSerializationSettings
        = new JsonSerializerSettings
{
    MetadataPropertyHandling = MetadataPropertyHandling.Ignore
};