18

我对我所有的代码运行 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

我想在这种情况下我仍然没有真正看到问题所在。我应该传入 along并从中设置日期吗?

沃尔特

4

5 回答 5

43

我认为这里的关键是if

如果实例由不受信任的代码访问,并且对可变对象的未经检查的更改会危及安全性或其他重要属性,则您将需要做一些不同的事情。

所以换句话说,如果你想要一个不可变的对象(即你没有setBirthdate()方法),你的代码是不正确的,因为有人可以写:

Date date = user.getBirthDate();
date.setMonth(1);  // mutated!

因此,您可能需要以下内容:

public Date getBirthDate()
{return new Date(birthDate.getTime());}  // essentially a clone
于 2009-11-14T00:44:17.787 回答
6

是的,我不会真正将其称为“安全”问题......我的意思是,究竟是哪个攻击者会针对您的对象编写恶意代码?真正的问题是您很可能会因意外调用getBirthDate然后修改结果而绊倒。

Date出于这个原因,当您将 getter 用作值类型时,通常会让您的 getter 克隆可变对象(例如用于返回)。

(你也可以争辩说 JavaDate不应该是可变的,但现在对此无能为力。)

于 2009-11-14T01:12:44.253 回答
4

除了 Matt Solnit 的好答案之外,我在设置属性时也遇到了同样的问题,所以我也做了同样的事情:

public void setDataEmissaoNota (Date dataEmissaoNota)
{
    this.dataEmissaoNota = new Date(dataEmissaoNota.getTime());
}

工作正常!

于 2015-08-06T20:13:55.817 回答
2

好吧,我会说这一切都取决于。返回不可变对象还有其他与安全无关的原因,因为如果对象被滥用,它还可能导致代码中出现一些难以发现的错误。

类是否会被不受信任的代码和/或数据访问?如果是这样,您需要清楚地了解您的应用程序在验证输入方面的责任。

另外,应用程序的性质是什么?如果它是例如一个外部可访问的网络服务,那么输入几乎可以肯定被认为是潜在的恶意。但是,如果它是在本地运行的应用程序,没有从受信任的来源获取输入的权限,那么可能无需担心。

于 2009-11-14T00:53:20.080 回答
0

我更喜欢以 EpochTime 格式将 Date 存储为 Long 并将其用于在我的应用程序层中持久保存。这不需要任何额外的 Lombok getter 覆盖。最后,在提供响应时,我可以有一个 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;

}

于 2020-07-23T20:38:07.503 回答