defmodule ToweropsWeb.Plugs.GraphQLIntrospection do @moduledoc """ Blocks GraphQL introspection queries in production. Introspection exposes the full schema to API consumers. This is useful in development but should be disabled in production to reduce attack surface. """ import Plug.Conn def init(opts), do: opts def call(conn, _opts) do if Application.get_env(:towerops, :env) == :prod and introspection_query?(conn) do conn |> put_resp_content_type("application/json") |> send_resp(400, Jason.encode!(%{errors: [%{message: "Introspection is disabled"}]})) |> halt() else conn end end defp introspection_query?(conn) do case conn.body_params do %{"query" => query} when is_binary(query) -> String.contains?(query, "__schema") or String.contains?(query, "__type") _ -> false end end end