Skip to content

Commit 2a0302a

Browse files
committed
Create allow list for event when intospection is blocked but developers
really want to use certain subqueries.
1 parent 29ffb8a commit 2a0302a

4 files changed

Lines changed: 28 additions & 2 deletions

File tree

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ I wanted to monitor the queries and responses of our graphql endpoint. Still, we
4848
| `CACHE_TTL` | The cache TTL | `60` |
4949
| `LOG_LEVEL` | The log level | `info` |
5050
| `BLOCK_SCHEMA_INTROSPECTION`| Blocks the schema introspection | `false` |
51+
| `ALLOWED_INTROSPECTION` | Allow only certain queries in introspection | `` |
5152
| `ENABLE_ACCESS_LOG` | Enable the access log | `false` |
5253
| `READ_ONLY_MODE` | Enable the read only mode | `false` |
5354
| `ALLOWED_URLS` | Allow access only to certain URLs | `/v1/graphql,/v1/version` |
@@ -107,6 +108,15 @@ You can enable the read-only mode by setting the `READ_ONLY_MODE` environment va
107108

108109
You can allow access only to certain URLs by setting the `ALLOWED_URLS` environment variable to a comma-separated list of URLs. If enabled - other URLs will return `403 Forbidden` error and request will **not** reach the proxied service.
109110

111+
### Blocking introspection
112+
113+
You can block the schema introspection by setting the `BLOCK_SCHEMA_INTROSPECTION` environment variable to `true` - which will block all the queries with introspection parts, like:
114+
115+
`__schema`, `__type`, `__typename`, `__directive`, `__directivelocation`, `__field`, `__inputvalue`, `__enumvalue`, `__typekind`, `__fieldtype`, `__inputobjecttype`, `__enumtype`, `__uniontype`, `__scalars`, `__objects`, `__interfaces`, `__unions`, `__enums`, `__inputobjects`, `__directives`
116+
117+
If you'd like to keep blocking of the schema introspection on but allow one or more of from the list of above for any reason, you can use the `ALLOWED_INTROSPECTION` environment variable to specify the list of allowed queries.
118+
119+
`ALLOWED_INTROSPECTION="__typename,__type"`
110120

111121
### Monitoring endpoint
112122

graphql.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,15 @@ func parseGraphQLQuery(c *fiber.Ctx) (operationType, operationName string, cache
9696
if cfg.Security.BlockIntrospection {
9797
for _, s := range oper.SelectionSet.Selections {
9898
for _, s2 := range s.GetSelectionSet().Selections {
99-
if _, exists := retrospectionQuerySet[s2.(*ast.Field).Name.Value]; exists {
99+
if _, exists := retrospectionQuerySet[strings.ToLower(s2.(*ast.Field).Name.Value)]; exists {
100+
if len(cfg.Security.IntrospectionAllowed) > 0 {
101+
for _, introspectionQueryAllowed := range cfg.Security.IntrospectionAllowed {
102+
if strings.EqualFold(strings.ToLower(introspectionQueryAllowed), strings.ToLower(s2.(*ast.Field).Name.Value)) {
103+
cfg.Logger.Debug("Introspection query allowed, passing through", m)
104+
return
105+
}
106+
}
107+
}
100108
cfg.Logger.Warning("Introspection query blocked", m)
101109
cfg.Monitoring.Increment(libpack_monitoring.MetricsSkipped, nil)
102110
c.Status(403).SendString("Introspection queries are not allowed")

main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ func parseConfig() {
3030
c.Cache.CacheEnable = envutil.GetBool("ENABLE_GLOBAL_CACHE", false)
3131
c.Cache.CacheTTL = envutil.GetInt("CACHE_TTL", 60)
3232
c.Security.BlockIntrospection = envutil.GetBool("BLOCK_SCHEMA_INTROSPECTION", false)
33+
c.Security.IntrospectionAllowed = func() []string {
34+
urls := envutil.Getenv("ALLOWED_INTROSPECTION", "")
35+
if urls == "" {
36+
return nil
37+
}
38+
return strings.Split(urls, ",")
39+
}()
3340
c.Logger = libpack_logging.NewLogger()
3441
c.Client.GQLClient = graphql.NewConnection()
3542
c.Client.GQLClient.SetEndpoint(c.Server.HostGraphQL)

struct_config.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type config struct {
4040
}
4141

4242
Security struct {
43-
BlockIntrospection bool
43+
BlockIntrospection bool
44+
IntrospectionAllowed []string
4445
}
4546
}

0 commit comments

Comments
 (0)