Skip to content

Commit

Permalink
Filter sensitive data from inspect(Tesla.Client.t)
Browse files Browse the repository at this point in the history
  • Loading branch information
maltoe committed Jun 17, 2022
1 parent 392ce43 commit 2516dff
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
42 changes: 42 additions & 0 deletions lib/tesla/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,46 @@ defmodule Tesla.Client do
defp unruntime({module, :call, [[]]}) when is_atom(module), do: module
defp unruntime({module, :call, [opts]}) when is_atom(module), do: {module, opts}
defp unruntime({:fn, fun}) when is_function(fun), do: fun

defimpl Inspect do
@filtered "[FILTERED]"

@sensitive_opts %{
Tesla.Middleware.BasicAuth => [:username, :password],
Tesla.Middleware.BearerAuth => [:token],
Tesla.Middleware.DigestAuth => [:username, :password]
}

def inspect(%Tesla.Client{} = client, opts) do
client
|> Map.update!(:pre, &filter_sensitive_opts/1)
|> Inspect.Any.inspect(opts)
end

defp filter_sensitive_opts([]), do: []

defp filter_sensitive_opts([{middleware, :call, [opts]} | rest]) do
sensitive_opts = Map.get(@sensitive_opts, middleware, [])
filtered_opts = Enum.reduce(sensitive_opts, opts, &maybe_redact(&2, &1))

[{middleware, :call, filtered_opts} | filter_sensitive_opts(rest)]
end

defp filter_sensitive_opts([middleware | rest]) do
[middleware | filter_sensitive_opts(rest)]
end

defp maybe_redact(opts, key) do
cond do
is_map(opts) and is_map_key(opts, key) ->
Map.put(opts, key, @filtered)

is_list(opts) and Keyword.has_key?(opts, key) ->
Keyword.put(opts, key, @filtered)

true ->
opts
end
end
end
end
15 changes: 15 additions & 0 deletions test/tesla/client_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,19 @@ defmodule Tesla.ClientTest do
assert middlewares == Tesla.Client.middleware(client)
end
end

describe "Inspect.Tesla.Client" do
test "ensures that no secrets are leaked in logs" do
middlewares = [
{Tesla.Middleware.BasicAuth, username: "secret", password: "secret", other: "OK"},
{Tesla.Middleware.BearerAuth, token: "secret", other: "OK"},
{Tesla.Middleware.DigestAuth, username: "secret", password: "secret", other: "OK"}
]

inspected = middlewares |> Tesla.client() |> inspect()

refute String.contains?(inspected, "secret")
assert String.contains?(inspected, "OK")
end
end
end

0 comments on commit 2516dff

Please sign in to comment.