如何防止用户修改不属于他们的资源?

How Do I Prevent Users From Modifying Resources They Do Not Own?

我正在编写一个服务器,其中我有一个实体 StoreOwner "owns" 或者与 Store 实体有 @OneToMany 关系(一个店主有 1 到N 家商店)。每个 StoreOfferItem,每个也与商店有 @OneToMany 关系(一个商店有 1 到 N 个报价和 1 到 N 个项目)。

我已经在使用 GWT Xsrf 保护 每次登录后与登录用户关联的会话 ID (cookie)。

关于会话 ID 的一件事: 当然,会话 ID 在用户 "identified" 自己输入他的用户名和密码后被放置在我的数据库中。无论用户是否被黑客攻击、丢失笔记本电脑或正确输入凭据:用户在我的服务器上都算作已登录——它应该如何更好地了解?但是..

恕我直言,缺少一件事:如果登录(已验证)用户向服务器发送 delete 请求,其中包含他不拥有商店的商品 ID也不拥有?目前,我正在 StoreService:

// StoreService.java

@Transactional
public ItemDTO deleteItem(String sessionId, Long storeId, ItemDTO itemDto) {

    // sessionId is the cookie I have placed in my database
    // This way I want to ensure that I am only accessing a store
    // that is associated with the logged in store owner (the user basically)
    Store store = this.storeOwnerRepository.getStore(sessionId, storeId);

    Item item = ConvertDTO.convertItem(store, itemDto);

    // Check if the store ID that I got using the cookie is the
    // same ID as the store ID from the item that should be deleted
    if(item .getStore().getId() == store.getId()) {
        item = this.storeOwnerRepository.deleteItem(item);
    } else {
        // If this didn't work we have a potentially hostile user:
        throw new RuntimeException("Is somebody trying to delete items of a store he doesn't own?");
    }

    itemDto = ConvertEntity.convertItem(item);
    return itemDto;
}

这是我第一次尝试编写更大的服务器应用程序,我想防止用户做这样的事情。

我的问题是双重的:[1] 我正在做的事情真的会阻止登录用户将他不拥有的另一家商店的 ID 走私到我的服务器吗?另外,[2]我可以稍微简化一下吗?

我的问题是,随着应用程序的增长,有时可能会忘记这项检查

if(item .getStore().getId() == store.getId()) { /* .. */ }

当然,我可以将它移到我的 StoreOwnerRepository 中,但我有更好的选择吗?

It is possible to replicate session IDs. Any user with knowledge of your data could use the above method to delete resources, particularly if the method is exposed via the web as an endpoint. Unless some form of validation mechanism is in place, passing and using the session ID is not inherently secure

在不了解更多关于您的应用程序架构的情况下,这就是我所能回答的范围。

作为恶意用户,我会问:"What do I need to do to do damage?"

  1. 会话 ID
  2. 商店ID
  3. 项目的结构
  4. 以上所有信息是如何发送到后端的(XML、JSON等)

知道这些信息,使用某种应用程序,如 Fiddler or PostMan,我可以向您的后端发送虚假请求。

那么,问题是,上面的哪些内容很容易被发现,并且复制起来有多容易?答案是:可能没那么难。换句话说,上面的实施不会阻止用户执行我刚才提到的操作(同样,不了解您的应用程序)。

Hibernate 本身不是一种安全提供机制 - 它的唯一责任是 ORM。您可能会考虑研究 Spring Security - 更好地启用更具可扩展性的安全措施。

根据您有权访问的信息,您需要确定一种方法来最好地防止用户伪造他们的身份。会话 ID 似乎是可以伪造的。