在《有效的Java》(第7章)中,它说
还要注意的是,我们没有使用Date的clone方法来进行防御性复制,因为Date是非final的,所以clone方法不能保证返回一个类为java.util.Date的对象:它可能返回专门为恶意破坏设计的不受信任子类的示例。例如,此类子类可能在创建时记录对私有静态列表中每个示例的引用,并允许攻击者访问此列表。这将给予攻击者可以自由支配所有示例。要防止此类攻击,不要使用clone方法对类型可被不受信任方子类化的参数进行防御性复制。
我不太明白它的解释。为什么clone()不返回Date对象?示例怎么可能是不可信子类?
4条答案
按热度按时间vxqlmq5t1#
请看下面的代码:
因为
copyOfMaliciousDate
的类型是Date
,所以可以调用clone()
,它将返回一个Date
对象,但是在copyOfMaliciousDate
上调用clone
将执行在MaliciousDate
类的clone()
中编写的代码,因为存储在copyOfMaliciousDate
中的 * instance * 是一个MaliciousDate
。0vvn1miw2#
clone()
被广泛认为是一个失败的实验,原因有很多,在这种情况下,传入Date
的某个人可能传入了EvilDate extends Date
,其clone()
方法偷偷返回了一个仍然可以被其他人修改的副本。zynd9foi3#
我没有读过你引用的那本书,但那一段理由很差,而且没有提供任何保护措施来抵御任何攻击。
引文提到,能够将代码加载到程序中的攻击者可能会使用恶意方法提交
Date
子类,例如从clone
返回Date
的子类。但这只是具有加载代码能力的攻击者造成危害的一个次要方面。他们还可能:
System.exit()
停止程序,并如果攻击者正在您的进程中运行代码,那么游戏就结束了,您的进程也受到了危害,而这个愚蠢的小防护装置也帮不上什么忙。
也许您认为克隆从设计的Angular 来看是不好的,这没关系,但是请不要假装不使用它会保护您免受某些安全威胁,因为它不会。
cedebl8k4#
由于Date类不是final类,因此可以扩展该类,并重写clone方法以存储示例,以后可以访问这些示例来修改状态。
MaliciousDate.java
Period.java