Recently I had the opportunity to study security best practices for GraphQL. One security recommendation that stood out as low-hanging fruit was disabling GraphQL introspecting for your API in production. GraphQL libraries I have used for Ruby and JavaScript made doing this very easy, so I was expecting the same thing with the Absinthe library in Elixir. It then surprised me that disabled introspection in Absinthe was documented, and every more confusing to figure out how.
Luckily after some web searching, I stumbled upon a Gist made by the community with middleware to disable introspection. So for my own implementation, I decided to make it simpler and disable introspection entirely if you are not in the development environment. Check it out.
defmodule MyAppWeb.Schema.Middleware.AuthorizedIntrospection do @moduledoc """ Disable schema introspection outside of development """ @behaviour Absinthe.Plugin @impl Absinthe.Plugin def before_resolution(exec) do if Enum.find(exec.result.emitter.selections, fn %{name: field_name} -> Macro.underscore(field_name) == "__schema" && Mix.env() != :dev end) do %{ exec | validation_errors: [ %Absinthe.Phase.Error{message: "Unauthorized", phase: __MODULE__} ] } else exec end end @impl Absinthe.Plugin def after_resolution(exec), do: exec @impl Absinthe.Plugin def pipeline(pipeline, _exec), do: pipeline end
Top comments (1)
Note that Mix.env is not available in releases.
See hexdocs.pm/mix/Mix.html#env/0