GraphQL 关系泄漏数据,即使已设置 context.user 解析器。如何通过关系防止数据泄露?
GraphQL relations leaking data, even with context.user resolver already set. How to prevent data exposure via relations?
大家是怎么跨关系做认证的,防止数据被关系穿越的?
例如我们有一个有用户的商店。
// Returns error as i've set custom resolver to allow only context.user.is_shop_owner
{
shops {
name
users {
email
...
}
}
}
此查询通常会被 context.user.is_shop_owner
等自定义解析器阻止,因此您无法从根查询执行此查询。
但是,如果恶意人员遍历关系到达用户对象,他就能够获取敏感的用户数据。
// Data exposed un-intendedly due to relation traversal. How to prevent this?
{
products {
name
price
shop {
users { ... } // boom, exposed
}
}
}
这是 graphql 的缺陷吗? 你们是如何解决这个问题的?
顺便说一句,这是在 python-石墨烯堆栈上。
编辑:顺便说一句,我知道我们可以做到 exclude_fields
,但是我将无法从 ShopNode 访问用户,这是查询 ShopNode 的重要信息,因此限制字段是可能不是一个好主意。 (已编辑)
这大概应该控制在Shop
类型内,到return null
当用户没有合适的权限时。否则,如果从第二个字段访问 Shop
,则必须重复检查。
我最终为每个节点设置自定义解析器,以根据 context.user
阻止您想要限制访问的关系。参考下面的代码回答我上面的问题。
class ProductNode(DjangoObjectType):
class Meta:
model = Product
interfaces = (graphene.relay.Node)
# Exclude nodes where you do not need any access at all
exclude_fields = ['users']
# For nodes where you need specific/limited access, define custom resolvers.
# This prevents the relation traversal loophole
def resolve_shop(self, args, context, info):
""" Allow access to nodes only for staff or shop owner and manager """
if get_is_staff_user(context.user, self):
return self.shop
Operations.raise_forbidden_access_error()
大家是怎么跨关系做认证的,防止数据被关系穿越的?
例如我们有一个有用户的商店。
// Returns error as i've set custom resolver to allow only context.user.is_shop_owner
{
shops {
name
users {
email
...
}
}
}
此查询通常会被 context.user.is_shop_owner
等自定义解析器阻止,因此您无法从根查询执行此查询。
但是,如果恶意人员遍历关系到达用户对象,他就能够获取敏感的用户数据。
// Data exposed un-intendedly due to relation traversal. How to prevent this?
{
products {
name
price
shop {
users { ... } // boom, exposed
}
}
}
这是 graphql 的缺陷吗? 你们是如何解决这个问题的?
顺便说一句,这是在 python-石墨烯堆栈上。
编辑:顺便说一句,我知道我们可以做到 exclude_fields
,但是我将无法从 ShopNode 访问用户,这是查询 ShopNode 的重要信息,因此限制字段是可能不是一个好主意。 (已编辑)
这大概应该控制在Shop
类型内,到return null
当用户没有合适的权限时。否则,如果从第二个字段访问 Shop
,则必须重复检查。
我最终为每个节点设置自定义解析器,以根据 context.user
阻止您想要限制访问的关系。参考下面的代码回答我上面的问题。
class ProductNode(DjangoObjectType):
class Meta:
model = Product
interfaces = (graphene.relay.Node)
# Exclude nodes where you do not need any access at all
exclude_fields = ['users']
# For nodes where you need specific/limited access, define custom resolvers.
# This prevents the relation traversal loophole
def resolve_shop(self, args, context, info):
""" Allow access to nodes only for staff or shop owner and manager """
if get_is_staff_user(context.user, self):
return self.shop
Operations.raise_forbidden_access_error()