Blocking introspection queries.

This commit is contained in:
2023-10-08 18:07:24 +01:00
parent eee6016b5a
commit 3ac7c115aa
8 changed files with 62 additions and 4 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ help: ## display this help
.PHONY: run
run: ## run application
@LOG_LEVEL=debug JWT_USER_CLAIM_PATH="Hasura.x-hasura-user-id" HOST_GRAPHQL=https://hasura8.lan/v1/graphql go run *.go
@LOG_LEVEL=debug BLOCK_SCHEMA_INTROSPECTION=true JWT_USER_CLAIM_PATH="Hasura.x-hasura-user-id" HOST_GRAPHQL=https://hasura8.lan/v1/graphql go run *.go
.PHONY: build
build: ## build the binary
+2
View File
@@ -20,3 +20,5 @@ Creates a passthrough proxy to a graphql endpoint(s), allowing you for analysis
`CACHE_TTL` - the cache TTL (default: `60s`)
`LOG_LEVEL` - the log level (default: `info`)
`BLOCK_SCHEMA_INTROSPECTION` - blocks the schema introspection (default: `false`)
+2
View File
@@ -8,6 +8,7 @@ require (
github.com/gookit/goutil v0.6.12
github.com/graphql-go/graphql v0.8.1
github.com/json-iterator/go v1.1.12
github.com/k0kubun/pp v3.0.1+incompatible
github.com/lukaszraczylo/ask v0.0.0-20230927103145-2ff1123b4415
github.com/lukaszraczylo/go-simple-graphql v1.1.31
github.com/telegram-bot-app/libpack v0.0.0-20231008100411-9f7f8bf94315
@@ -20,6 +21,7 @@ require (
github.com/avast/retry-go/v4 v4.5.0 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/gookit/color v1.5.4 // indirect
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/lukaszraczylo/pandati v0.0.29 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
+4
View File
@@ -28,6 +28,10 @@ github.com/graphql-go/graphql v0.8.1 h1:p7/Ou/WpmulocJeEx7wjQy611rtXGQaAcXGqanuM
github.com/graphql-go/graphql v0.8.1/go.mod h1:nKiHzRM0qopJEwCITUuIsxk9PlVlwIiiI8pnJEhordQ=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40=
github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/lukaszraczylo/ask v0.0.0-20230927103145-2ff1123b4415 h1:lvI8Wlbg4PxkRcg2f10wgoaRpfN19v+YdRek3+dLtlM=
+42 -1
View File
@@ -4,10 +4,34 @@ import (
fiber "github.com/gofiber/fiber/v2"
"github.com/graphql-go/graphql/language/ast"
"github.com/graphql-go/graphql/language/parser"
"github.com/k0kubun/pp"
libpack_monitoring "github.com/telegram-bot-app/libpack/monitoring"
)
func parseGraphQLQuery(c *fiber.Ctx) (operationType, operationName string, cacheRequest bool) {
var retrospection_queries = []string{
"__schema",
"__type",
"__typename",
"__directive",
"__directivelocation",
"__field",
"__inputvalue",
"__enumvalue",
"__typekind",
"__fieldtype",
"__inputobjecttype",
"__enumtype",
"__uniontype",
"__scalars",
"__objects",
"__interfaces",
"__unions",
"__enums",
"__inputobjects",
"__directives",
}
func parseGraphQLQuery(c *fiber.Ctx) (operationType, operationName string, cacheRequest bool, should_block bool) {
m := make(map[string]interface{})
err := json.Unmarshal(c.Body(), &m)
if err != nil {
@@ -44,7 +68,24 @@ func parseGraphQLQuery(c *fiber.Ctx) (operationType, operationName string, cache
cacheRequest = true
}
}
if cfg.Security.BlockIntrospection {
for _, s := range oper.SelectionSet.Selections {
for _, s2 := range s.GetSelectionSet().Selections {
pp.Println(s2.(*ast.Field).Name.Value)
for _, introspection_query := range retrospection_queries {
if s2.(*ast.Field).Name.Value == introspection_query {
cfg.Logger.Warning("Introspection query blocked", m)
cfg.Monitoring.Increment(libpack_monitoring.MetricsSkipped, nil)
c.Status(403).SendString("Introspection queries are not allowed")
should_block = true
return
}
}
}
}
}
}
}
return
}
+1
View File
@@ -18,6 +18,7 @@ func parseConfig() {
c.Client.JWTUserClaimPath = envutil.Getenv("JWT_USER_CLAIM_PATH", "")
c.Cache.CacheEnable = envutil.GetBool("CACHE_ENABLE", false)
c.Cache.CacheTTL = envutil.GetInt("CACHE_TTL", 60)
c.Security.BlockIntrospection = envutil.GetBool("BLOCK_SCHEMA_INTROSPECTION", false)
c.Logger = libpack_logging.NewLogger()
c.Client.GQLClient = graphql.NewConnection()
c.Client.GQLClient.SetEndpoint(c.Server.HostGraphQL)
+5 -1
View File
@@ -50,7 +50,11 @@ func processGraphQLRequest(c *fiber.Ctx) error {
if authorization != nil && len(cfg.Client.JWTUserClaimPath) > 0 {
extracted_user_id = extractClaimsFromJWTHeader(string(authorization))
}
opType, opName, cache_from_query := parseGraphQLQuery(c)
opType, opName, cache_from_query, should_block := parseGraphQLQuery(c)
if should_block {
return nil
}
was_cached := false
+4
View File
@@ -29,4 +29,8 @@ type config struct {
CacheTTL int
CacheClient *cache.Cache
}
Security struct {
BlockIntrospection bool
}
}