CA5360:在反序列化中不要调用危险的方法
属性 | 值 |
---|---|
规则 ID | CA5360 |
标题 | 在反序列化中不要调用危险的方法 |
类别 | 安全性 |
修复是中断修复还是非中断修复 | 非中断 |
在 .NET 9 中默认启用 | 否 |
原因
在反序列化中调用以下其中一个危险方法:
- System.IO.Directory.Delete
- System.IO.DirectoryInfo.Delete
- System.IO.File.AppendAllLines
- System.IO.File.AppendAllText
- System.IO.File.AppendText
- System.IO.File.Copy
- System.IO.File.Delete
- System.IO.File.WriteAllBytes
- System.IO.File.WriteAllLines
- System.IO.File.WriteAllText
- System.IO.FileInfo.Delete
- System.IO.Log.LogStore.Delete
- System.Reflection.Assembly.GetLoadedModules
- System.Reflection.Assembly.Load
- System.Reflection.Assembly.LoadFrom
- System.Reflection.Assembly.LoadFile
- System.Reflection.Assembly.LoadModule
- System.Reflection.Assembly.LoadWithPartialName
- System.Reflection.Assembly.ReflectionOnlyLoad
- System.Reflection.Assembly.ReflectionOnlyLoadFrom
- System.Reflection.Assembly.UnsafeLoadFrom
所有符合以下其中一项要求的方法都可以是反序列化的回调:
- 标记有 System.Runtime.Serialization.OnDeserializingAttribute。
- 标记有 System.Runtime.Serialization.OnDeserializedAttribute。
- 实现 System.Runtime.Serialization.IDeserializationCallback.OnDeserialization。
- 实现 System.IDisposable.Dispose。
- 为析构函数。
规则说明
不安全的反序列化是一种漏洞。当使用不受信任的数据来损害应用程序的逻辑,造成拒绝服务 (DoS) 攻击,或甚至在反序列化时任意执行代码,就会出现该漏洞。 应用程序对受其控制的不受信任数据进行反序列化时,恶意用户很可能会滥用这些反序列化功能。 具体来说,就是在反序列化过程中调用危险方法。 如果攻击者成功执行不安全的反序列化攻击,就能实施更多攻击,如 DoS 攻击、绕过身份验证和执行远程代码。
如何解决冲突
从自动运行的反序列化回调中删除这些危险方法。 仅在验证输入后调用危险方法。
何时禁止显示警告
在以下情况下,可禁止显示此规则的警告:
- 已知输入为受信任输入。 考虑应用程序的信任边界和数据流可能会随时间发生变化。
- 序列化的数据不会被篡改。 序列化后,对序列化的数据进行加密签名。 在反序列化之前,验证加密签名。 保护加密密钥不被泄露,并设计密钥轮换。
- 验证数据对应用程序安全。
抑制警告
如果只想抑制单个冲突,请将预处理器指令添加到源文件以禁用该规则,然后重新启用该规则。
#pragma warning disable CA5360
// The code that's violating the rule is on this line.
#pragma warning restore CA5360
若要对文件、文件夹或项目禁用该规则,请在配置文件中将其严重性设置为 none
。
[*.{cs,vb}]
dotnet_diagnostic.CA5360.severity = none
有关详细信息,请参阅如何禁止显示代码分析警告。
伪代码示例
冲突
using System;
using System.IO;
using System.Runtime.Serialization;
[Serializable()]
public class ExampleClass : IDeserializationCallback
{
private string member;
void IDeserializationCallback.OnDeserialization(Object sender)
{
var sourceFileName = "malicious file";
var destFileName = "sensitive file";
File.Copy(sourceFileName, destFileName);
}
}
解决方案
using System;
using System.IO;
using System.Runtime.Serialization;
[Serializable()]
public class ExampleClass : IDeserializationCallback
{
private string member;
void IDeserializationCallback.OnDeserialization(Object sender)
{
var sourceFileName = "malicious file";
var destFileName = "sensitive file";
// Remove the potential dangerous operation.
// File.Copy(sourceFileName, destFileName);
}
}