3

FindBugs 提出了一个名为EI_EXPOSE_REP的错误,其描述如下:

EI:可能通过返回对可变对象的引用来公开内部表示

返回对存储在对象字段之一中的可变对象值的引用会公开对象的内部表示。如果实例由不受信任的代码访问,并且对可变对象的未经检查的更改会危及安全性或其他重要属性,则您将需要做一些不同的事情。在许多情况下,返回对象的新副本是更好的方法。

关于 SO ( 123 ) 的几个问题已经解决了如何避免此类错误,我理解这是防止修改不可变对象的开发最佳实践但是我不清楚为什么此类错误属于 MALICIOUS_CODE 类别.

这背后的真正威胁是什么?

如果这是一个恶意代码问题,攻击者几乎可以做任何他想做的事情,而可变性不会是最大的问题。如果它是一个漏洞,那么只有在执行不受信任的代码时才能利用它,而且我看不到任何符合这种情况的用例。

对此有何看法?

谢谢 !

4

2 回答 2

2

关键是,任何时候你打开一个实现,你都会冒着故意或以其他方式破坏代码的风险。显然,一个恶意的图书馆用户,例如,可以只是拆解你的 jar 并以这种方式了解细节——关键是要尽量减少暴露的风险:它无法被消除。

访问您的库的外部代码的一个简单示例:

考虑一些简单的东西,比如拥有访问级别的对象。如果它是可变的,那么可以想象图书馆用户可以设置自己的访问级别。任何合理的库都很少会公开这种微不足道的事情,但这是一个内部表示何时可能被滥用的明显例子。

底线是暴露的可变状态使代码难以推理,也难以保护。您的代码或其他人可能会意外或故意修改您自己的代码/库使用的某些内容。如果您的库随后更改其行为而没有考虑到这一点,您可能会引入一个微妙(或不那么微妙)的错误。

于 2013-01-02T15:48:28.083 回答
1

让对象隐藏状态并提供强大的静态接口的能力是 Java 移动代码安全性的核心。程序员搞砸了这件事可能会导致漏洞的方式有很多种。

对于值对象,请考虑String. 我们相信任何情况都String不会改变。我们不想验证 [check] 一个特定的文件名,例如,我们不希望它在我们实际使用它时改变(注意,java.io.File在这个意义上不能很好地工作)。此外,可变内部可能具有恶意equals方法(例如),由封闭类调用equals,但恶意获取对其他封闭类实例的内部对象的引用。

引用类型通常是对象能力。通常,它们会削弱它们被赋予的对象的能力(通过构造函数传递)。比如说,您只能通过您有权访问的实例将文件写入特定目录,但它有一个能够写入整个文件系统的字段。

然后是 Java 2 安全模型,这绝不是一件好事。内部对象可能有在特权上下文中调用的方法,这通常不是问题。现在,恶意方放置在对象(受信任类型)中,该对象执行了在该上下文中不应该执行的操作。

当然,请注意随机子类化类。他们可能会get在未来的版本中获得一种方法。

话虽如此,我认为 Findbugs 的这个警告没有帮助。该代码可能并非有意隐藏该对象。

(有关暴露内部对象问题的详细描述,请参阅 Michael Feathers有效使用遗留代码的第 13 章(和第 14 章) 。)

于 2013-01-03T01:05:41.883 回答