fix: disable graphql introspection queries when disableIntrospectionInProduction is true (#12982)

This commit is contained in:
Jarrod Flesch
2025-07-02 08:33:20 -04:00
committed by GitHub
parent 57d00ad2e9
commit a9580e05ac
4 changed files with 37 additions and 8 deletions

View File

@@ -16,14 +16,15 @@ The labels you provide for your Collections and Globals are used to name the Gra
At the top of your Payload Config you can define all the options to manage GraphQL. At the top of your Payload Config you can define all the options to manage GraphQL.
| Option | Description | | Option | Description |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mutations` | Any custom Mutations to be added in addition to what Payload provides. [More](/docs/graphql/extending) | | `mutations` | Any custom Mutations to be added in addition to what Payload provides. [More](/docs/graphql/extending) |
| `queries` | Any custom Queries to be added in addition to what Payload provides. [More](/docs/graphql/extending) | | `queries` | Any custom Queries to be added in addition to what Payload provides. [More](/docs/graphql/extending) |
| `maxComplexity` | A number used to set the maximum allowed complexity allowed by requests [More](/docs/graphql/overview#query-complexity-limits) | | `maxComplexity` | A number used to set the maximum allowed complexity allowed by requests [More](/docs/graphql/overview#query-complexity-limits) |
| `disablePlaygroundInProduction` | A boolean that if false will enable the GraphQL playground, defaults to true. [More](/docs/graphql/overview#graphql-playground) | | `disablePlaygroundInProduction` | A boolean that if false will enable the GraphQL playground in production environments, defaults to true. [More](/docs/graphql/overview#graphql-playground) |
| `disable` | A boolean that if true will disable the GraphQL entirely, defaults to false. | | `disableIntrospectionInProduction` | A boolean that if false will enable the GraphQL introspection in production environments, defaults to true. |
| `validationRules` | A function that takes the ExecutionArgs and returns an array of ValidationRules. | | `disable` | A boolean that if true will disable the GraphQL entirely, defaults to false. |
| `validationRules` | A function that takes the ExecutionArgs and returns an array of ValidationRules. |
## Collections ## Collections

View File

@@ -113,6 +113,7 @@ export function configToSchema(config: SanitizedConfig): {
variables: args.variableValues, variables: args.variableValues,
// onComplete: (complexity) => { console.log('Query Complexity:', complexity); }, // onComplete: (complexity) => { console.log('Query Complexity:', complexity); },
}), }),
...(config.graphQL.disableIntrospectionInProduction ? [NoProductionIntrospection] : []),
...(typeof config?.graphQL?.validationRules === 'function' ...(typeof config?.graphQL?.validationRules === 'function'
? config.graphQL.validationRules(args) ? config.graphQL.validationRules(args)
: []), : []),
@@ -123,3 +124,18 @@ export function configToSchema(config: SanitizedConfig): {
validationRules, validationRules,
} }
} }
const NoProductionIntrospection: GraphQL.ValidationRule = (context) => ({
Field(node) {
if (process.env.NODE_ENV === 'production') {
if (node.name.value === '__schema' || node.name.value === '__type') {
context.reportError(
new GraphQL.GraphQLError(
'GraphQL introspection is not allowed, but the query contained __schema or __type',
{ nodes: [node] },
),
)
}
}
},
})

View File

@@ -123,6 +123,7 @@ export const addDefaultsToConfig = (config: Config): Config => {
config.endpoints = config.endpoints ?? [] config.endpoints = config.endpoints ?? []
config.globals = config.globals ?? [] config.globals = config.globals ?? []
config.graphQL = { config.graphQL = {
disableIntrospectionInProduction: true,
disablePlaygroundInProduction: true, disablePlaygroundInProduction: true,
maxComplexity: 1000, maxComplexity: 1000,
schemaOutputFile: `${typeof process?.cwd === 'function' ? process.cwd() : ''}/schema.graphql`, schemaOutputFile: `${typeof process?.cwd === 'function' ? process.cwd() : ''}/schema.graphql`,

View File

@@ -1029,6 +1029,17 @@ export type Config = {
*/ */
graphQL?: { graphQL?: {
disable?: boolean disable?: boolean
/**
* Disable introspection queries in production.
*
* @default true
*/
disableIntrospectionInProduction?: boolean
/**
* Disable the GraphQL Playground in production.
*
* @default true
*/
disablePlaygroundInProduction?: boolean disablePlaygroundInProduction?: boolean
maxComplexity?: number maxComplexity?: number
/** /**