通过广度限制GraphQL查询

时间:2019-12-06 20:21:13

标签: security graphql graphql-js apollo-server express-graphql

有很多文章,教程甚至模块可以通过检查查询的深度,成本或对GraphQL服务器的高比率连续请求(DoS攻击)进行速率限制来限制恶意递归查询。

但是,我找不到能够保护GraphQL服务器不受“宽”查询的任何东西,该查询只是在同一请求中拉出太多字段实例,即:

query MaliciousQuery {
  alias1: fieldName { subfileld1 subfiled2 ...}
  alias2: fieldName { subfileld1 subfiled2 ...}
  ...
  alias10: fieldName { subfileld1 subfiled2 ...}
  ...
  alias100: fieldName { subfileld1 subfiled2 ...}
  ...
  alias1000: fieldName { subfileld1 subfiled2 ...}
  ...
}

是的,GraphQL允许客户询问他们的需求,但是在某些情况下,我们可能希望限制特定类型的对象数量,特别是在获取此类对象的成本很高的情况下。我应该提到在我的用例中不希望使用分页。

当然,一种方法是限制查询字符串的总长度,但这是完成此操作的粗略方法,并且对于甚至不涉及实际昂贵对象的复杂查询请求,也会产生意想不到的副作用。成本分析也可以使用,但是对于这种简单的东西来说似乎已经过头了,而且还会带来其他复杂性。

如果我们可以在架构上有一个限制指令来指定类似的东西,那将是很好的

@perRequestLimit(count: 5)

因此,客户在一次查询中最多只能请求5个这些昂贵的对象。

有人知道这样的模块吗?还是有其他方法可以实现这种限制?

2 个答案:

答案 0 :(得分:0)

更好的方法是仅使用查询成本或查询复杂性分析。 existing libraries可以解析请求的查询,确定成本并在成本超出设置的允许值时拒绝请求。这样一来,您就可以轻松控制查询的深度和广度,而不必将单个查询“白名单”,因为扩展性不是很好。

答案 1 :(得分:0)

看来,即使我认为这应该是GraphQL的核心功能,也不存在这样的模块/实现,尤其是因为这可能是一个很大的DoS漏洞,并且如上所述,在某些情况下,成本/复杂性分析可能会过大(如我们的特定情况)。

我最终编写了一个简单的@resourceLimit指令,以限制使用别名多次请求单个字段。当我们认为有必要时,这仍然使我们可以选择增加成本/复杂性分析,但是目前,它可以满足我们的有限需求。