56

我的 dto 类中有以下代码。

public void setBillDate(Date billDate) {
    this.billDate = billDate;
}

而且我在声纳中遇到了这样的错误,我不确定我在这里做错了什么。

Malicious code vulnerability - May expose internal representation by incorporating reference to mutable object   

该类是一个dto,该方法是自动创建的setter方法。我在这里做错了什么。如果有人能解释一下。这将是一个很大的帮助。

4

8 回答 8

114

Date是可变的

使用该设置器,有人可以无意中从外部修改日期实例

考虑这个

class MyClass {

   private Date billDate;


   public void setBillDate(Date billDate) {
      this.billDate = billDate;
   }

}

现在有人可以设置它

MyClass m = new MyClass();

Date dateToBeSet = new Date();
m.setBillDate(dateToBeSet); //The actual dateToBeSet is set to m

dateToBeSet.setYear(...); 
//^^^^^^^^ Un-intentional modification to dateToBeSet, will also modify the m's billDate 

为避免这种情况,您可能需要在设置之前进行深层复制

public void setBillDate(Date billDate) {
    this.billDate = new Date(billDate.getTime());
}
于 2013-09-23T08:36:26.410 回答
49

我想知道为什么没有一个解决方案考虑 null 。一个通用的、null 安全的解决方案应该如下所示:

public void setBillDate(Date billDate) {
    this.billDate = billDate != null ? new Date(billDate.getTime()) : null;
}
于 2014-01-14T12:49:53.657 回答
3

Date是可变的

而且您并没有创建传入您的参数的副本。 Date所以如果客户端代码会改变Date对象的值,它也会影响你的类。

解决方案是创建一个副本Date

public setBillDate(Date billDate){
   this.billDate = new Date(billDate.getTime());
}
于 2013-09-23T08:39:04.713 回答
3

也可以考虑使用克隆。不要忘记空检查。

public void setBillDate(Date billDate) {
    this.billDate = billDate == null ? null : billDate.clone();
}
于 2015-04-27T11:44:01.940 回答
3

除了现有的答案之外,我还提出了一个基于OptionalJava 8 类的新版本。

public void setBillDate(Date billDate) {
    this.billDate = Optional
            .ofNullable(billDate)
            .map(Date::getTime)
            .map(Date::new)
            .orElse(null);
}
于 2017-07-27T06:52:17.530 回答
3

一个反驳的论点可能是,为什么人们会无意中修改日期?如果客户端设置值然后修改它,那么我们的代码应该反映它,不是吗?如果不是,那么它不会令人困惑吗?

我宁愿忽略这个 FindBugs 警告。

如果您想这样做,只需在您的 Maven 中添加以下依赖项pom.xml

<!-- Findbugs -->
        <dependency>
            <groupId>com.google.code.findbugs</groupId>
            <artifactId>annotations</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.findbugs</groupId>
            <artifactId>annotations</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.findbugs</groupId>
            <artifactId>jsr305</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>

然后是 POJO 中类或成员字段级别的这些注释:

@SuppressFBWarnings(value = { "EI_EXPOSE_REP", "EI_EXPOSE_REP2" }, justification = "I prefer to suppress these FindBugs warnings")

干杯

阿克谢

于 2017-08-17T03:11:58.807 回答
1

日期不是一成不变的,即您的 billDate 可以在您的 DTO 对象上设置后更改。或者,在代码中:

Date billDate = new Date();
dto.setBillDate(billDate);
billDate.setYear(1990);
// now, dto.getBillDate().getYear() == 1990

您可以使您的二传手更安全:

public void setBillDate(Date billDate) {
    this.billDate = (Date)billDate.clone();
}
于 2013-09-23T08:38:09.653 回答
1

最佳答案 37 不是正确答案:没人关心 NullPointerExceptions???

你应该试试这个:

public void setBillDate(Date billDate) {
    this.billDate = billDate == null ? billDate : new Date(billDate.getTime());
}
于 2015-09-21T10:42:56.627 回答