🛡️ GraphQL-Armor 🛡️

🛡️ GraphQL-Armor 🛡️ is a Dead-simple, yet highly customizable security middleware for Apollo GraphQL servers.
Contents
Supported remediations
Remediations enabled by default
Installation
npm install @escape.tech/graphql-armor
yarn add @escape.tech/graphql-armor
API
import { GQLArmor } from '@escape.tech/graphql-armor';
GQLArmor(
config?: GQLArmorConfig,
onPluginUpdate?: PluginUpdateEvent,
)
GQLArmor.getPlugins()
=> PluginDefinition[]
GQLArmor.getValidationRules()
=> ValidationRule[]
GQLArmor.getConfig<ContextFunctionParams>(
apolloConfig: Config<ContextFunctionParams>
): Config<ContextFunctionParams>
GQLArmor.apolloServer(
apolloConfig: Config<ContextFunctionParams>
): ApolloServer<ContextFunctionParams>
import { ArmoredConfig, ArmoredConfigU } from '@escape.tech/graphql-armor';
ArmoredConfig(
apolloConfig: Config<ContextFunctionParams>,
armorConfig?: GQLArmorConfig,
)
ArmoredConfigU(
config: {
validationRules: ValidationRule[],
plugins: PluginDefinition[],
...
},
) -> config{...}
Examples
Apollo Server
Applying remediation from GraphQL-Armor
import { GQLArmor } from '@escape.tech/graphql-armor';
const armor = new GQLArmor({});
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [...armor.getPlugins(), ...yourPlugins],
validationRules: [...armor.getValidationRules(), ...yourValidationRules],
});
Patching the configuration through GraphQL-Armor
import { ArmoredConfig } from '@escape.tech/graphql-armor';
const server = new ApolloServer(ArmoredConfig({
typeDefs,
resolvers,
cache: 'bounded',
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
}))
Instanciating ApolloServer from GraphQL-Armor
import { GQLArmor } from '@escape.tech/graphql-armor';
const armor = new GQLArmor({});
const server = armor.apolloServer({
typeDefs,
resolvers,
cache: 'bounded',
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});
NestJS
Applying remediation from GraphQL-Armor
import { GQLArmor } from '@escape.tech/graphql-armor';
@Module({
imports: [
GraphQLModule.forRoot({
...
validationRules: [...armor.getValidationRules(), ...yourRules],
plugins: [...armor.getPlugins(), ...yourPlugins],
}),
],
})
Wrapping factory with GraphQL-Armor
import { ArmoredConfig } from '@escape.tech/graphql-armor';
@Module({
imports: [
GraphQLModule.forRoot({
...
useFactory() => {
return ArmoredConfig({
validationRules: [yourRules],
plugins: [yourPlugins],
});
}
}),
],
})
Patching factory with GraphQL-Armor
import { GQLArmor } from '@escape.tech/graphql-armor';
const armor = new GQLArmor({});
@Module({
imports: [
GraphQLModule.forRoot({
...
useFactory() => {
return {
validationRules: [armor.getValidationRules(), yourRules],
plugins: [armor.getPlugins(), yourPlugins],
};
}
}),
],
})
Others
Inheritence from Apollo Config
import { ArmoredConfig } from '@escape.tech/graphql-armor';
const config = ArmoredConfig({
plugins: [...yourPlugins],
validationRules: [...yourRules]
});
Others types
import { ArmoredConfigU } from '@escape.tech/graphql-armor';
const config = ArmoredConfigU({
plugins: [...yourPlugins],
validationRules: [...yourRules]
});
Configuration
Character Limit
Character Limit plugin
will enforce a character limit on your GraphQL queries.
(Note: The limit is not applied to whole HTTP body -, multipart form data / file upload will still works)
{
CharacterLimit: {
enabled: true,
options: {
maxLength: 15000,
},
}
}
Cost Analysis
Cost Analysis plugin
analyze incoming GraphQL queries and apply cost analysis algorithm to prevent resource overload.
{
CostAnalysis: {
enabled: true,
options: {
maxCost: 1000,
},
}
}
Block Introspection
BlockIntrospection plugin
will prevent introspection queries from being executed.
By default, introspection is still available for our Live GraphQL Security Testing Platform by providing a valid identifier.
{
BlockIntrospection: {
enabled: true,
options: {
headersWhitelist: {
'x-allow-introspection': 'allow',
...(process.env.ESCAPE_IDENTIFIER ? { 'x-escape-identifier': process.env.ESCAPE_IDENTIFIER } : {}),
},
},
}
}
Field Suggestion
Field Suggestion plugin
will prevent suggesting fields of unprecise GraphQL queries.
{
FieldSuggestion: {
enabled: true,
}
}
Environment Variables
Permissions
GraphQL-Armor support toggling remediations via environment variables.
We use a bitwise operation to switch the remediation on and off, this way, you can toggle multiple remediations using one variable.
export GQLARMOR_PERMISSIONS=-1
export GQLARMOR_PERMISSIONS=0
Character Limit | 0x1 |
Cost Analysis | 0x2 |
Introspection | 0x4 |
Field Suggestion | 0x8 |
For example, if you want to toggle ONLY
the Character Limit
and Cost Analysis
remediations, you can use the following environment variable:
export GQLARMOR_PERMISSIONS=$(python -c "print(0x1 | 0x2)")
If you want to toggle ONLY
the Introspection
remediation, you can use the following environment variable:
export GQLARMOR_PERMISSIONS=$(python -c "print(0x4)")
Events
onPluginUpdate
export type PluginUpdateEvent = (status: PluginState, plugin: PluginConfig) => void;
export enum PluginState {
ENABLED = 'enabled',
DISABLED = 'disabled',
REGISTERED = 'registered',
UNREGISTERED = 'unregistered',
}