GraphQL vs REST:常见的GraphQL安全样例

iso60001  680天前

22.png

传统的REST模型在完成多个任务时需要多个调用,例如将货物送到你手中和在网上订购食物。因为这是两个不同的活动,因此需要两个不同的调用。但是,GraphQL就像一个私人助理,一旦你提供了必要的详细信息,比如你的地址和个人兴趣,它就会为你完成任务。你只需简单地表达自己想要什么,然后等待它们的出现。换句话说,GraphQL是一种为你的兴趣服务的标准语言,就像上述示例中的私人助手一样。每个graphQL端点都由诸如Apollo服务器或基于heroku的图形引擎之类的graphQL服务器来处理。

从技术来看,REST API很少调用POST、GET、DELETE、PUT等方法去执行多个API操作,通常从多个端点进行加载数据,但GraphQL API可以通过单个请求中获得应用所需的所有数据。这主要是通过将一个端点作为同时处理多个请求或查询的graph端点来实现的,所有相关数据都是从这个端点获取的。通常这类端点是以以下名称结尾:/graphql/graph/graphql.php。而REST和GRAPHQL API中查询方式的区别如下所示:

33.png

44.png

55.png

在graphQL中,查询(query)是为了某些响应而发送的请求。如果可以使用一种更复杂的mutation(更像是编程中的函数)发出请求,那么就可以查询并修改多项特定数据。

66.png

而解析器(resolver)会告诉GraphQL如何以及在何处获取与给定字段对应的数据。你可以自定义解析器,这对于构造API非常有用。例如,若希望从电子图书馆网站检索著作的名称和作者,可以定义如下解析器:

const resolvers = {
Query: {
author(parent, args, context, info) {
return find(authors, { id: args.id });
},
},
Author: {
books(author) {
return filter(books, { author: author.name });
},
},
};

当发出查询{ author { books } }时,将调用Query.author解析器并将结果传递给Author.books。最后的结果将包含Author.books的返回值,嵌套在data.author.books中。

现在让我们来看看常见的安全测试用例:

声明:在开始之前,你可能需要一个名为GraphQL Raider的扩展和一个grapql可视化应用(https://apis.guru/graphql-voyager/)。通过graphql-voyager,你可以以交互式关系图直观地检查GraphQL API。你也可以从官方网站下载GraphiQL GUI界面,更好的进行GrapQL查询(https://electronjs.org/apps/graphiql)。

Test case 1:

如前所述,grapQL端点通常包含/graph/graphql。现在,尝试在查询参数中插入一个内省查询。默认情况下,内省查询(introspection query)是一个已定义好的查询,帮助用户了解由graphQL服务器定义的schema,了解服务器端支持何种类型的查询。你可以在这里看到详细信息。

将这个查询复制下来,粘贴到graphQL请求的查询参数处,然后发送。如果服务端允许此类查询,那么就会返回所使用的schema,有时还会给出细节,示例如下。

77.png

在某些情况下,内省查询所返回的某些敏感信息可帮助你更好地进行下一步攻击。

Test case 2:

如果你觉得某些响应很复杂,可以尝试通过GraphQL-voyager工具把其可视化,也许你很快就能看到某些特殊的东西。一般来说,你可以看到与graphQL相关的所有端点和API调用的复杂关联。此时,你就可以对每个端点进行身份验证检测。

88.png

Test case3:

你也可以下载并使用官方的GraphiQL GUI界面来检索有价值的数据。在极少数情况下,可视化程序可能不会列出所有可用的mutation(更改数据的方式),此时这个官方界面就派上了用场。

99.png

100.png

在上图中,我们使用了文档中MyMutations所展示的可用mutation(在示例中是modifyBug),编写了一个查询。记住要遵循语法,并理解参数的意义(这类似于编程中的一个预定义的函数)。

对于这个modifyBug,它需要text、id、private值作为输入。

而mutation和查询变量的配合如下所示:

110.png

如果mutation中存在一个以`!`结尾的参数,那么就表示这是强制需求的参数。我们的例子中并不存在。

数据修改前:

120.jpg

数据修改后:

图片.png

因此,我们可以利用GraphiQL interface对mutation进行访问控制检查(权限有关)。

如果不能调用任何mutation,我们可能会得到一行安全错误,这可能能证明服务器和graphQL的配置是安全的。

总之,测试所有的mutation和查询,寻找是否存在任何敏感信息泄露或权限配置错误的漏洞。

Test case 4:

查询变量不正确所输出的错误信息可能也会有大用。而在graphQL服务与数据库所进行的交互中,尽管不常见,但仍然存在SQL注入的可能性。

某个服务报错信息如下所示:

140.png

在GraphQL中,有些情况下不解析就处理SQL查询,从而直接在数据库上执行SQL查询并给出数据。这种情况的示例如下:

150.png

GraphQL的安全性当然不止以上所述,软件可能会有补丁,但任何软件都是人写的。在你发现之前,漏洞将一直存在。

本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场
来源:https://medium.com/@apkash8/graphql-vs-rest-api-model-common-security-test-cases-for-graphql-endpoints-5b723b1468b4

最新评论

昵称
邮箱
提交评论