Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions lib/error_tracker/integrations/plug.ex
Original file line number Diff line number Diff line change
Expand Up @@ -111,21 +111,27 @@ defmodule ErrorTracker.Integrations.Plug do
conn |> build_context |> ErrorTracker.set_context()
end

@sensitive_headers ["cookie", "authorization"]

defp build_context(conn = %Plug.Conn{}) do
%{
"request.host" => conn.host,
"request.path" => conn.request_path,
"request.query" => conn.query_string,
"request.method" => conn.method,
"request.ip" => remote_ip(conn),
"request.headers" => conn.req_headers |> Map.new() |> Map.drop(@sensitive_headers),
"request.headers" => conn.req_headers |> Map.new() |> Map.reject(&should_not_be_leaked?/1),
# Depending on the error source, the request params may have not been fetched yet
"request.params" => unless(is_struct(conn.params, Plug.Conn.Unfetched), do: conn.params)
}
end

@sensitive ~w[cookie auth key secret token password credential private]

defp should_not_be_leaked?({key, _value}) do
downcased = key |> String.downcase()

Enum.any?(@sensitive, &String.contains?(downcased, &1))
end

defp remote_ip(conn = %Plug.Conn{}) do
remote_ip =
case Plug.Conn.get_req_header(conn, "x-forwarded-for") do
Expand Down
15 changes: 15 additions & 0 deletions test/integrations/plug_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ defmodule ErrorTracker.Integrations.PlugTest do
conn
|> Plug.Conn.put_req_header("cookie", "who stole the cookie from the cookie jar ?")
|> Plug.Conn.put_req_header("authorization", "Bearer plz-dont-leak-my-secrets")
|> Plug.Conn.put_req_header("authentication-helper", "hunter42")
|> Plug.Conn.put_req_header("important-token", "abcxyz")
|> Plug.Conn.put_req_header("private-name", "Some call me... Tim")
|> Plug.Conn.put_req_header("special-credential", "drink-your-ovaltine")
|> Plug.Conn.put_req_header("special-key", "Begin Private Key; dontleakmeplz")
|> Plug.Conn.put_req_header("special-secret", "Shh, it's a secret")
|> Plug.Conn.put_req_header("special-password", "correct-horse-battery-staple")
|> Plug.Conn.put_req_header("safe", "this can be safely stored in cleartext")

IntegrationPlug.report_error(
Expand All @@ -51,7 +58,15 @@ defmodule ErrorTracker.Integrations.PlugTest do

assert "cookie" not in header_names
assert "authorization" not in header_names
assert "authentication-helper" not in header_names
assert "important-token" not in header_names
assert "private-name" not in header_names
assert "special-credential" not in header_names
assert "special-key" not in header_names
assert "special-password" not in header_names
assert "special-secret" not in header_names

assert "safe" in header_names
assert length(header_names) == 1
end
end
Loading