Allow only specific queries
Prevent malicious requests to your GraphQL servers by specifying allowed queries.For example, you might know that clients send only a limited set of GraphQL queries to your servers. To prevent your GraphQL servers from resolving potentially malicious requests, you specify that list of expected queries so that the servers immediately return an error for queries that are not in that list.
Before you begin
- Set up Gloo Gateway in a single cluster.
- Deploy sample apps.
- Configure an HTTP listener on your gateway. The
RouteTable
in this guide is not required, because you create a GraphQL-specific route table instead. - Follow the Get started with GraphQL in Gloo Gateway guide to define example GraphQL schema and resolvers and configure routing.
Configure policies to allow specific GraphQL queries
You can apply a GraphQLAllowedQueryPolicy
policy at the route level. For more information, see Applying policies.
Review the following sample configuration files.
apiVersion: security.policy.gloo.solo.io/v2
kind: GraphQLAllowedQueryPolicy
metadata:
name: bookinfo-allowed-queries
namespace: bookinfo
spec:
applyToRoutes:
- route:
labels:
route: graphql-bookinfo
config:
allowedQueryHashes:
- <query_hash>
Review the following table to understand this configuration. For more information, see the API docs.
Setting | Description |
---|---|
spec.applyToRoutes |
Use labels to configure which GraphQL routes to apply the policy to. This example label matches the app and route from the example route table that you previously applied in the GraphQL getting started guide. If omitted or empty, the policy applies to no routes in the workspace. If more than one GraphQLAllowedQueryPolicy applies to a GraphQL route, the oldest policy is applied. |
allowedQueryHashes |
A list of SHA-256 hashed GraphQL queries that you allow the GraphQL server to resolve. Queries that are not sent as hashes are hashed and compared against the list. If a query hash is not in this list, the server returns an error. If ommitted or empty, all queries are allowed. |
Verify a GraphQLAllowedQueryPolicy
-
Apply the example policy in your cluster.
kubectl apply -f - << EOF apiVersion: security.policy.gloo.solo.io/v2 kind: GraphQLAllowedQueryPolicy metadata: name: bookinfo-allowed-queries namespace: bookinfo spec: applyToRoutes: - route: labels: route: graphql-bookinfo config: allowedQueryHashes: - 4b5aa540520d96aa073dbb8ded86bdb405429d08c5d942f8a24ca1a3d5b3ecf6 EOF
The specified SHA-256 hash represents the following GraphQL query:
query { productsForHome { title ratings { reviewer numStars } } }
-
Send the allowed GraphQL query to the route through the ingress gateway.
curl -vik --resolve www.example.com:80:${INGRESS_GW_IP} http://www.example.com:80/graphql \ -d '{"query":"query { productsForHome { title ratings {reviewer numStars}} }"}'
curl -vik --resolve www.example.com:443:${INGRESS_GW_IP} https://www.example.com:443/graphql \ -d '{"query":"query { productsForHome { title ratings {reviewer numStars}} }"}'
-
Verify that you receive the expected response from your GraphQL server.
{"data":{"productsForHome":[{"title":"The Comedy of Errors","ratings":[{"reviewer":"Reviewer1","numStars":5},{"reviewer":"Reviewer2","numStars":4}]}]}}
-
Send a different GraphQL query that is not listed in the policy to the route.
curl -vik --resolve www.example.com:80:${INGRESS_GW_IP} http://www.example.com:80/graphql \ -d '{"query":"query { productsForHome { ratings {reviewer numStars}} }"}'
curl -vik --resolve www.example.com:443:${INGRESS_GW_IP} https://www.example.com:443/graphql \ -d '{"query":"query { productsForHome { ratings {reviewer numStars}} }"}'
-
Verify that you now receive an error from the GraphQL server.
{"errors":[{"message":"hash 722215b914d51efb9474eb72688c8fafaeaa4a6548c3fd57d83192e9ccfd2198 not found in allowlist for query: 'query { productsForHome { ratings {reviewer numStars}} }'"}]}
-
Optional: Clean up the resource that you created.
kubectl -n bookinfo delete GraphQLAllowedQueryPolicy bookinfo-allowed-queries