我针对我的所有代码运行findbugs,只处理最重要的事情。我终于解决了最重要的问题,现在我正在查看细节。我有一个简单的实体,比如用户:
public class User implements Serializable
{
protected Date birthDate;
public Date getBirthDate()
{return(birthDate);}
public void setBirthDate(final Date birthDate)
{this.birthDate = birthDate;}
}
这个课程不完整,所以不要因为它错过了serialVersionUID
和其他标准内容,我只关心birthDate
安全漏洞。
现在,根据findbugs报告,由于我返回对可变对象的引用,这是一个潜在的安全风险。但在实践中,这究竟有多重要?
http://findbugs.sourceforge.net/bugDescriptions.html#EI_EXPOSE_REP
我想在这种情况下我仍然没有真正看到问题所在。我应该传递long
并设置日期吗?
沃尔特
答案 0 :(得分:34)
我认为这里的关键是 if :
如果不受信任的代码访问实例,并且对可变对象的未经检查的更改会危及安全性或其他重要属性,则需要执行不同的操作。
所以换句话说, if 你想要一个不可变对象(即你没有setBirthdate()
方法),你的代码是不正确的,因为有人可以写:
Date date = user.getBirthDate();
date.setMonth(1); // mutated!
所以你可能会想要以下内容:
public Date getBirthDate()
{return new Date(birthDate.getTime());} // essentially a clone
答案 1 :(得分:5)
是的,我不会真的把它称为“安全”问题......我的意思是,攻击者到底会针对你的对象编写恶意代码?真正的问题是,你很可能会因意外调用getBirthDate
然后修改结果而绊倒。
出于这个原因,当您将它们用作值类型时,通常会使用getter clone可变对象(如Date
)进行返回。
(你也可以说Java的Date
不应该变得可变,但现在没有太多可以做的。)
答案 2 :(得分:2)
好吧,我会说完全取决于。返回不可变对象还有其他与安全无关的原因,因为如果对象被滥用,它也可能导致代码中出现一些难以发现的错误。
该类是否会被不受信任的代码和/或数据访问?如果是这样,您需要清楚地了解应用程序在验证输入方面的责任。
此外,该应用程序的性质是什么?如果它是例如一个外部可访问的网络服务,那么输入几乎肯定会被认为是潜在的恶意。但是,如果它是一个本地运行的应用程序,没有从受信任的来源获得输入的特权,那么可能不需要担心。
答案 3 :(得分:2)
添加Matt Solnit的好答案,我在设置属性时遇到了同样的问题,所以我做了同样的事情:
public void setDataEmissaoNota (Date dataEmissaoNota)
{
this.dataEmissaoNota = new Date(dataEmissaoNota.getTime());
}
工作很好!
答案 4 :(得分:0)
我更喜欢将Date以EpochTime格式存储为Long,并将其用于在我的应用程序层中持久保存。不需要对Lombok吸气剂进行任何额外的覆盖。最后,在提供响应的同时,我可以具有一个util函数,该函数会将纪元时间戳转换为日期,然后将其作为字符串返回。可能做下面的事情::
private String Epoch_to_ISO8601(Long savedTimeStamp) {
Date passedDate = new Date(savedTimeStamp);
String ISO8601_date =
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssX")
.withZone(ZoneOffset.UTC)
.format(passedDate.toInstant());
return ISO8601_date;
}