diff --git a/lib/flame/fly_backend.ex b/lib/flame/fly_backend.ex index 9d15b22..3d15760 100644 --- a/lib/flame/fly_backend.ex +++ b/lib/flame/fly_backend.ex @@ -373,10 +373,26 @@ defmodule FLAME.FlyBackend do http_post!(url, remaining_tries - 1, opts) {:ok, {{_, status, reason}, _, resp_body}} -> - raise "failed POST #{url} with #{inspect(status)} (#{inspect(reason)}): #{inspect(resp_body)} #{inspect(headers)}" + raise "failed POST #{url} with #{inspect(status)} (#{inspect(reason)}): #{inspect(resp_body)} #{inspect(redact(headers))}" {:error, reason} -> - raise "failed POST #{url} with #{inspect(reason)} #{inspect(headers)}" + raise "failed POST #{url} with #{inspect(reason)} #{inspect(redact(headers))}" + end + end + + @redacted_headers ~w(authorization proxy-authorization) + + # The machines API is called with the Fly API token as a bearer credential, and + # the errors above are raised into logs and error trackers. Keep the header + # names, which are what you want when debugging a failed request, but drop the + # values of the ones that carry credentials. + defp redact(headers) do + for {name, value} <- headers do + if String.downcase(to_string(name)) in @redacted_headers do + {name, "[REDACTED]"} + else + {name, value} + end end end diff --git a/test/fly_backend_test.exs b/test/fly_backend_test.exs index c4e8d4b..67a88ce 100644 --- a/test/fly_backend_test.exs +++ b/test/fly_backend_test.exs @@ -82,6 +82,22 @@ defmodule FLAME.FlyBackendTest do assert Runner.new(backend: FLAME.FlyBackend) end + test "boot failures do not leak the API token" do + # Nothing is listening on this port, so the POST fails and remote_boot raises. + opts = [token: "super-secret", image: "img", app: "app", host: "http://127.0.0.1:1"] + runner = new({FlyBackend, opts}) + assert {:ok, init} = runner.backend_init + + err = + assert_raise RuntimeError, fn -> + FlyBackend.remote_boot(%{init | parent_ref: make_ref()}) + end + + refute err.message =~ "super-secret" + assert err.message =~ "Authorization" + assert err.message =~ "[REDACTED]" + end + test "parent backend attributes" do assert %FLAME.Parent{ pid: _,