某些对象自身可保持安全状态。您不应将这些对象传递给不受信任的代码,如果这样,后者会获得超越它自身权限的安全授权。
以创建一个 FileStream 对象为例。在创建该对象时需要 FileIOPermission,如果成功,将返回文件对象。但是,如果将该对象引用传递给没有文件权限的代码,则该对象将能够读/写此特定文件。
对此类对象的最简单防御措施是,通过公共 API 元素要求试图获得该对象引用的所有代码都拥有相同的 FileIOPermission。
序列化使用序列化可以允许其他代码看到或修改以其他方式不可访问的对象实例数据。同样,执行序列化的代码也需要拥有特殊的权限:SecurityPermission.SerializationFormatter。在默认策略下,该权限不会授予从 Internet 下载的代码或 Intranet 代码;只有本地机器上的代码才会被授予该权限。
正常情况下,对象实例的所有字段均被序列化,这意味着数据将以实例的序列化数据形式表示。这样,代码就可以解释该格式以确定数据值是什么,这与成员的可访问性无关。同样,反序列化将从序列化表现形式中提取数据并直接设置对象状态,这同样也与可访问性规则无关。
对于可以包含安全敏感数据的任何对象来说,应使该对象不可序列化(如果可能)。如果它必须是可序列化的,请尝试使包含敏感数据的特定字段不可序列化。如果无法这样做,则应知道该数据将被公开给有权进行序列化的任何代码,并确保没有恶意代码可以获得该权限。
ISerializable 接口的原定用途是仅供序列化基础结构使用。但是,如果未受保护,它也会潜在地泄漏敏感信息。如果通过实现 ISerializable 来提供自定义序列化,则应确保采取以下预防措施:
•应通过请求 SecurityPermission.SerializationFormatter 权限,或者确保方法输出中未包含敏感信息,来显式地确保 GetObjectData 的安全。例如:
[SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter =true)] public override void GetObjectData(SerializationInfo info, StreamingContext context) •用于序列化的特殊构造函数还应执行彻底的输入验证,并且应当受保护或是私有的,以避免被恶意代码滥用。它应当实施相同的安全检查以及通过其他手段(通过某类工厂显式创建或间接创建)获得该类的实例所需的权限。
应用程序域跨域问题要在托管宿主环境中隔离代码,常用方法是:使用降低各种程序集权限级别的显式策略,来创建多个子应用程序域。但是,在默认的应用程序域中,这些程序集的策略保持不变。如果其中一个子应用程序域可以强制默认应用程序域加载程序集,这就会失去代码隔离的效果,并且这些程序集中的类型将能够以更高的信任级别运行代码。
一个应用程序域可以强制另一个应用程序域加载某个程序集,并通过调用驻留在其他应用程序域中的对象的代理来运行所包含的代码。要获得跨应用程序域代理,宿主该对象的应用程序域必须提供一个代理(通过一个方法调用参数或返回值),或者,如果该应用程序域刚刚创建,则创建者将拥有 AppDomain 对象的代理。因此,要避免破坏代码隔离,具有较高信任级别的应用程序域不应将对其域中的 MarshalByRefObject 对象的引用提供给具有较低信任级别的应用程序域。
通常,默认应用程序域在创建子应用程序域时会在每一个子域中包含一个控件对象。控件对象可管理新的应用程序域,并且有时会从默认应用程序域获取命令,但实际上它不并知道如何直接与域联系。有时,默认应用程序域将调用它的控件对象代理。但是,有时可能需要控件对象能够回调到默认应用程序域。在这些情况下,默认应用程序域会将按引用封送的回调对象传递给控件对象的构造函数。控件对象负责保护该代理。如果控件对象打算将代理放到公共类的公共静态字段上,或者公开地公开该代理,那么这会为其他代码回调到默认应用程序域创造一个危险的机制。因此,控件对象始终被隐式信任,以保持代理的私有性。
文章来源于领测软件测试网 https://www.ltesting.net/