ID: 374 类型:基础 | 状态:草稿 |
描述
程序将非克隆可变数据作为参数发送给方法或函数。
扩展描述
已调用的函数或方法可以更改或删除可变数据。这可能违反调用函数对其状态所做的假设。在使用对可变数据的引用调用未知代码的情况下,此外部代码可以对发送的数据进行更改。如果以前没有克隆此数据,则修改后的数据在执行上下文中可能无效。
相关视图
与“研究层面”视图(CWE-1000)相关
与“开发层面”视图(CWE-699)相关
引入模式
阶段 | 说明 |
实现 |
应用平台
语言
C (出现的可能性不确定)
C++ (出现的可能性不确定)
Java (出现的可能性不确定)
C# (出现的可能性不确定)
后果
范围 | 冲击 | 可能性 |
完整性 | 技术冲击: 修改内存 数据可能会被另一个函数篡改。 |
被利用的可能性:
一般
示例
例1
见下例.
(问题代码)
Example Language: C
private:
int foo;
complexType bar;
String baz;
otherClass externalClass;
public:
void doStuff() {
externalClass.doOtherStuff(foo, bar, baz)
}
在本例中,bar和baz将通过引用dootherstufacture()传递,dootherstufacture()可能会更改它们。
例2
在下面java例子中,“书店”类管理书店的销售,它包括针对“库存管理”和“销售数据库管理”的成员对象。“书店”类包含一个更新销售数据库和库存的方法。此方法使用为Book类提供的ISBN号从Bookstore库存对象中检索Book对象,然后调用Sales对象的方法更新销售信息,然后调用Inventory对象的方法更新Bookstore的库存。
(问题代码)
Example Language: Java
public class BookStore {
private BookStoreInventory inventory;
private SalesDBManager sales;
...
// constructor for BookStore
public BookStore() {
this.inventory = new BookStoreInventory();
this.sales = new SalesDBManager();
...
}
public void updateSalesAndInventoryForBookSold(String bookISBN) {
// Get book object from inventory using ISBN
Book book = inventory.getBookWithISBN(bookISBN);
// update sales information for book sold
sales.updateSalesInformation(book);
// update inventory
inventory.updateInventory(book);
}
// other BookStore methods
...
}
public class Book {
private String title;
private String author;
private String isbn;
// Book object constructors and get/set methods
...
}
但是,在本例中,检索并传递给Sales对象方法的Book对象可以通过该方法修改其内容。当book对象发送到库存对象更新库存的方法时,这可能会导致意外的结果。
在Java编程语言中,方法的参数是通过值传递的,但是在对象的情况下,对象的引用通过值传递给方法。当一个对象引用作为一个方法参数传递时,对象引用的副本将在该方法中生成,因此这两个引用都指向同一个对象。这允许通过保存对象引用副本的方法修改对象的内容。[RIF-74]
在这种情况下,在调用更新库存之前,可以使用Sales对象的方法修改Book对象的内容。
为了防止修改后的书籍对象的内容,应在方法呼叫销售对象之前制作一份书籍对象的副本。在随后的例子中,书籍对象的拷贝是用克隆()方法制成的,书籍对象的拷贝被转到销售对象的方法。这将防止原始书籍对象发生任何变化。
(正确代码)
Example Language: Java
...
public void updateSalesAndInventoryForBookSold(String bookISBN) {
// Get book object from inventory using ISBN
Book book = inventory.getBookWithISBN(bookISBN);
// Create copy of book object to make sure contents are not changed
Book bookSold = (Book) book.clone();
// update sales information for book sold
sales.updateSalesInformation(bookSold);
// update inventory
inventory.updateInventory(book);
}
...
应对措施
阶段: 实现 传入不应更改为常量或不可变的数据。 |
阶段: 实现 克隆所有可变数据,然后将其传递到外部函数。这是首选的缓解措施。这样,不管对数据做了什么更改,都会保留一个有效的副本供类使用。 |
种属