如何预防Graphql安全问题

1,Auth验证
我们得根据header里的Authorization参数来验证改用户的session信息,同时将一些全局变量入userId, accountId 等存入context,而不是通过API 参数传入进来

2, 任何参数的输入验证
需严格对待每一个传进来的参数,如userId等,需验证这个信息是否和该用户的Authorization匹配

3,权限控制
如果系统有需做权限管理的时候,需验证任何一个操作该用户是否有正确的权限去更新和获取信息

3,Graphql 安全配置
ApolloServer在生产环境上以下配置需disable,防止代码信息泄露
introspection,
playground
tracing,
debug

限制验证配置

1,限制query的深度级数, 可采用插件 graphql-depth-limit, 避免内存被耗尽。

1
2
3
4
5
6
7
8
9
10
11
import depthLimit from 'graphql-depth-limit'
import express from 'express'
import graphqlHTTP from 'express-graphql'
import schema from './schema'

const app = express()

app.use('/graphql', graphqlHTTP((req, res) => ({
  schema,
  validationRules: [ depthLimit(10) ]
})))

2,限制用户/客户端对query和mutation的请求频率, 如果公司已经对所有的api请求已经用了第三方公司对DDOS进行了保护,那么该插件可不用。

1
2
3
4
5
6
7
8
9
10
import { createRateLimitDirective } from 'graphql-rate-limit'
const rateLimitDirective = createRateLimitDirective({ identifyContext: (ctx) => ctx.id });

export const schema = {
typeDefs,
resolvers,
schemaDirectives: {
rateLimit: rateLimitDirective,
},
}

3, 限制每个query参数的查询成本, 避免大量恶意的查询攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
import costAnalysis from 'graphql-cost-analysis'
import express from 'express'
import graphqlHTTP from 'express-graphql'
import schema from './schema'

const app = express()

app.use('/graphql', graphqlHTTP((req, res) => ({
  schema,
  validationRules: [
 costAnalysis({        variables: graphQLParams.variables,        maximumCost: 1000,      }),
]
})))

参考:
https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html