-1

我正在使用 keystonejs 6 和 nuxtjs 开发一个 JAMStack 项目。众所周知,keystonejs 使用 prisma 和 graphql(我猜是 apollo)在我们的数据模型上提供 CRUD(通用)操作。所以它使api(甚至graphql或rest)产生的错误也是由keystonejs产生的。现在的问题是当客户端向keystonjs发送错误的请求时,它会帮助客户端更正查询并给出提示。例如,如果我查询下一个请求:

await fetch("https://host:port/api/graphql", {
    "credentials": "include",
    "headers": {
        "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:94.0) Gecko/20100101 Firefox/94.0",
        "Accept": "*/*",
        "Accept-Language": "en-US,en;q=0.5",
        "Content-Type": "application/json",
        "Sec-Fetch-Dest": "empty",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Site": "same-site"
    },
    "referrer": "https://host:port/",
    "body": "{\"operationName\":null,\"variables\":{},\"query\":\"{\\n  navigationMenus(where: {status: {not: {equals: \\\"invisible\\\"}}}) {\\n    ida\\n    title\\n    pageURL\\n    childrenCount\\n    parent {\\n      id\\n      pageURL\\n      __typename\\n    }\\n    __typename\\n  }\\n}\\n\"}",
    "method": "POST",
    "mode": "cors"
});

由于字段 ida 无效,因此返回状态代码为 400 的错误请求错误(没问题),并且还帮助客户端提供以下响应:

errors  [ {…} ]
0   Object { message: "Cannot query field \"ida\" on type \"NavigationMenu\". Did you mean \"id\"?", locations: […], extensions: {…} }
message "Cannot query field \"ida\" on type \"NavigationMenu\". Did you mean \"id\"?"
locations   [ {…} ]
0   Object { line: 3, column: 5 }
line    3
column  5
extensions  Object { code: "GRAPHQL_VALIDATION_FAILED" }
code    "GRAPHQL_VALIDATION_FAILED"

所以这将导致一些漏洞,因为如果我忘记对某些字段进行正确的访问控制,攻击者可能会通过一些尝试找到字段名称并访问这些数据。
虽然我可以理解这不是一个很大的问题,但是有没有办法在生产中关闭 graphql 提示?

4

1 回答 1

0

Keystone 构建在 Apollo 之上,允许您在启动时通过graphql.apolloConfigconfig 选项将其他配置传递给 Apollo 服务器:

graphql.apolloConfig(默认值undefined:):允许您将额外的选项传递给ApolloServer构造函数。

Keystone 6:系统配置 API 文档

这可用于修改 Apollo 错误处理行为并用您自己的替换它。一个简单的示例可能如下所示:

import { config } from '@keystone-next/keystone';
import { lists } from './schema';

import { ValidationError } from 'apollo-server-express';
import { GraphQLError } from 'graphql';

export default config({
  db: {
    provider: 'sqlite',
    url: process.env.DATABASE_URL,
  },
  lists,
  graphql: {
    apolloConfig: {
      formatError: (error: GraphQLError): any => {
        if (error instanceof ValidationError) {
          return new ValidationError('Invalid request.');
        }
      }
    }
  }
});

任何尝试访问不存在字段的 GraphQL 查询都将收到响应:

{
  "errors": [
    {
      "message": "Invalid request.",
      "extensions": {
        "code": "GRAPHQL_VALIDATION_FAILED"
      }
    }
  ],
  "data": null
}

Apollo 以这种方式泄漏数据的一般问题正在 Apollo 存储库中进行跟踪,例如:Validation errors can be used to get schema details #2247。听起来正在取得进展。

于 2021-11-30T02:04:00.680 回答