确保数据只能由其实际所有者在数据库中更改

时间:2018-08-18 14:18:45

标签: sql database postgresql security database-design

背景

我们正在建立一个新项目,目前 在数据库设计。我们 偶然发现了一个问题 我们无法解决,我们相信我们 有一些解决方案,但我们不确定。 这个问题似乎有点不可思议, 可能是因为我们不够了解 该主题的关键字。

问题

在我们的案例中,我们正在构建一个rest-api 用户使用令牌进行身份验证的地方 对端点执行CRUD操作。

没关系,您需要提供一个 访问或修改资源的有效令牌。 标准的东西。

但是,通过身份验证不会阻止您修改行 那不属于你。

因此,用户可以更改其他用户的数据, 因为没有逻辑可以处理。 如果表彼此之间的位置很远,则不能依赖外键或主键约束-除非参阅解决方案2。

解决方案1 ​​

向每个只是值持有者或实际fk的表添加一个字段。 在我们的案例中,该字段引用了“所有者”或用户的主键。

解决方案2

获得出色表现,然后进行遍历 一直回到“所有者”的位置 对象/行。

解决方案3

实施RLS(行级安全性)解决方案,但 似乎不是RLS的用例或至少感觉到 对于我们的用例来说要先进一点。

问题

所以问题是,在仍能解决问题的同时,性能最高的是什么 安全问题?还有其他解决方案吗?

解决方案2示例:

表格

user
    id - pk
    … 

company 
    id - pk
    … 
    user_id - fk 

note
    id - pk
    … 
    user_id

会话

user_session
    user_id
    … 

数据用户可以更改:

SELECT
    *
FROM
    note
WHERE
    user_id = :session.user_id

当用户想要更新数据时:

UPDATE note
SET text = “foobar”
WHERE user_id = :session.user_id AND id=payload.id

如果存在与user_id相对应的行 给请求用户,以及提供的注释主键 存在。

参考

1 个答案:

答案 0 :(得分:0)

首先,您需要确定租户策略(“多租户”是您的关键字)。您可以将用户数据放置在不同的群集,数据库,模式或行中

每个数据库的租户是我的首选解决方案

  

似乎不是RLS的用例

这绝对是RLS的用例

在每个“受保护的”表中都需要一个“ owner_id”列。确保current_user是该所有者。级联外键以更新owner_id(如果更改)

您可以使用WITH CHECK OPTION视图代替RLS,但是RLS仍然更简单