随着前端技术的快速发展,越来越多的应用程序采用了 GraphQL 作为后端数据查询和交互的标准。GraphQL 旨在提供一种更高效、更灵活和更安全的数据查询机制。然而,在 GraphQL 中处理用户输入时,保障安全性仍然是一项重要的任务。
在本文中,我们将学习如何在 GraphQL 中安全地处理用户输入,探究此过程的深度和学习成果,并提供相关的指导意义和示例代码。
为什么安全性在 GraphQL 中如此重要?
任何应用程序中,安全性总是排在最优先的位置。使用 GraphQL 的应用程序也不例外。在 GraphQL 中,安全性特别重要,因为 GraphQL 的数据查询过程更加灵活,查询语句可以由客户端组成,其中包括对所有字段的查询、过滤以及排序。因此,GraphQL 在其语言本身中并没有像 RESTful API 那样实施 OAuth2、ClientCredentials 等身份验证和授权机制。如果不注意安全性问题,那么这些查询可能会被恶意的攻击者利用来获取一些敏感信息,或者进行一些恶意行为。
因此,实现安全的 GraphQL 函数是至关重要的。我们如何在 GraphQL 中实现安全的数据查询和输入处理呢?下面是一些我们可以采取的技术策略:
采取的策略:
- 使用静态分析工具- 开发人员使用像 ESLint 和 TSLint 这样的静态代码分析工具,以确保 GraphQL 查询中的验证和过滤器是正确的, 业务逻辑是一致的,能更好的保证 GraphQL 编排的正确性和数据查询的安全性。
- 启用安全 GraphQL 处理器- 当应用程序在生产环境中部署时,应该始终启用安全的 GraphQL 处理器,如graphql-shield,它会执行一些运行时的检查和过滤操作。它能在查询即将执行之前验证用户身份,显式地指定哪些查询字段是安全的,并能防止一些服务器端的技术攻击行为,如 DDoS 攻击和访问限制等。
- 对 GraphQL 查询进行身份验证和授权- 开发人员应该为所有 GraphQL API 的查询和突变设置身份验证和授权策略,以防止未授权的用户进行读写突变操作。GraphQL API 通常使用 jwt token 来实现身份验证,但也需要考虑 csrf 攻击和 DOS 攻击。
下面,我们来看看如何在 GraphQL 中安全地处理用户输入:
在 GraphQL 中安全地处理用户输入
一些开发人员在编写 GraphQL 代码时,可能会犯一些严重的安全错误,例如在客户端将查询字符串传递给服务器,或在数据库查询、更新或删除操作中使用未经验证的客户端输入。这些错误可能会导致服务器实现中的重大安全漏洞,使客户端的敏感信息遭到泄露,甚至使整个服务器暴露于攻击者的攻击之下。
为了避免这种情况,在 GraphQL 中,我们建议使用参数型式的查询,并使用对参数进行适当检验的安全数据访问模式。以下是在 GraphQL 中实现安全输入处理的步骤:
1. 使用参数查询签名来定义 GraphQL 文件
为了在 GraphQL 中安全处理输入,最简单的方法是使用 GraphQL 查询语言中的名称参数签名来定义 GraphQL 查询。以下是一个查询用户信息的示例:
query fetchUser($id: String!){ user(id: $id) { name email } }
在这个查询中,我们定义了名称为$id的字符串参数。接下来,我们需要通过传递这个参数来执行查询。
2. 在输入处理中尽可能地验证和过滤参数
在 GraphQL 中处理用户输入的重要方法是在输入处理中使用参数验证和过滤器机制。GraphQL 使用了一个名为 GraphQL 类型系统(GraphQL Type System)的强大系统,具有它自己的架构和规则。我们应该使用这个类别系统来定义 GraphQL 查询参数的类型,并使用它来检查 GraphQL 客户端的请求。
在 GraphQL 的类别系统中,有一些类型是内置的,例如 String、Int、Boolean 等。这些内置类型不能够满足完全灵活的需求。因此,我们可以通过创建自定义类型,来进行更灵活的输入验证和过滤。例如在以下示例中,我们可以使用 GraphQL 类型系统定义一个自定义类型 user,在类型中定义查询所需的每个字段,并在客户端-服务器端之间使用此类型来传递参数。
-- -------------------- ---- ------- ---- ---- - --- --- ----- ------- ------ ------ - ---- ----- - -------- ----- ---- ------ ------ -
在进行 GraphQL 查询之前,我们需要对每个参数进行适当的验证和过滤操作,在第一个示例中,我们只允许传递字符串类型的参数,其他的参数类型按需进行转化或选择忽略掉。
-- -------------------- ---- ------- ------ - -------------- -------------- - ---- ---------- ---- ------- -------------------- ----- -------- - --- ------------------- ----- ------- ------- - --- - ----- ------------- -- ----- - ----- ------------- -- ------ - ----- ------------- -- - --- ----- ----- - --- ------------------- ----- -------- ------- - ------ - ----- --- ---------------------- ----- - ------ - ----- -------------- -- ----------- ------------ ------- ---- --- ----- -- -- -------- ------ -------- -- - -- ------------- - ---- --
3. 使用 GraphQL 鉴权和授权策略
我们针对以上提到的两种风险,保证在 GraphQL 数据查询和突变操作中,实现身份验证和授权策略。身份验证意味着能够验证客户端请求的用户身份。例如为每个请求所附带的 JWT token。如果请求是由未经身份验证的用户发起的,则拒绝响应该请求。授权策略则允许我们控制用户对查询和突变操作的访问权限。例如,我们可以在服务器端定义查询和突变操作的权限。
在客户端,可以将用户 JWT token 作为请求的请求头发送。例如:
Authorization: Bearer ${Token}
在服务器端,我们可以在执行查询之前,验证并解码 JWT token,以确定请求的用户身份是否有效。例如,在 ExpressJS 中我们可以编写一个中间件来进行检查,并在请求之前设置用户信息给 resolver:
-- -------------------- ---- ------- -- ------------------ ----- ------------ - ----- ----- ---- ----- -- - ----- ----- - ------------------------- -- --- -- -- ----- -------- ----- ---- - ---------------------- -- ------- - ------ ------------------------------------- - -------- - ----- ------- - -- ----- ----- --- - ---------- ----------------------
在执行查询之后,我们可以检查客户端查询的安全性。通过检查输入中的参数,我们可以对 GraphQL 查询进行足够的验证。例如,在 resolver 函数中,我们应该对 GraphQL 查询参数进行有效性验证,以确保它们符合期望的数据类型,并且没有构成任何安全风险。
-- -------------------- ---- ------- ------ - --------------- ------------------ ------------- - ---- ---------- ------ - --------- - ---- --------------- -- -- ---- ------ ------ ----- -------- - --- ------------------- ----- ------- ------------ ------ ------- ------ --- - ----- --- ----------------------------- -- ---------- - ----- ------------- -- --------- - ----- ------------- -- ------ - ----- ------------- -- -- -- -- -- ----- ------ ----- --------- - - ----- --- ------------------------- ----- - --- - ----- --- ------------------------------ -- -------- ----- -------- --------- ---- -------- ---- ----- ------- -- ------- ----- ------ - ------- ----- ---- - ----- ------------------------------------- ---------- ----- --- ----------- --- -------- - ------ ---- - -
总结
GraphQL 的灵活性使其成为前后端开发人员的首选选择。然而,这种灵活性也可能带来安全性问题。本文中,我们介绍了在 GraphQL 中安全处理用户输入的步骤,并提供了几种保护 GraphQL 查询和数据突变免受恶意攻击的策略。请务必注意在 GraphQL 实现中采取合适的安全措施。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64cc201d5ad90b6d04246a24