Skip to content

Commit c82aa6a

Browse files
committed
Avoid leaking any headers that appear like they may be sensitive
1 parent c3ace80 commit c82aa6a

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

lib/error_tracker/integrations/plug.ex

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,21 +111,27 @@ defmodule ErrorTracker.Integrations.Plug do
111111
conn |> build_context |> ErrorTracker.set_context()
112112
end
113113

114-
@sensitive_headers ["cookie", "authorization"]
115-
116114
defp build_context(conn = %Plug.Conn{}) do
117115
%{
118116
"request.host" => conn.host,
119117
"request.path" => conn.request_path,
120118
"request.query" => conn.query_string,
121119
"request.method" => conn.method,
122120
"request.ip" => remote_ip(conn),
123-
"request.headers" => conn.req_headers |> Map.new() |> Map.drop(@sensitive_headers),
121+
"request.headers" => conn.req_headers |> Map.new() |> Map.reject(&should_not_be_leaked?/1),
124122
# Depending on the error source, the request params may have not been fetched yet
125123
"request.params" => unless(is_struct(conn.params, Plug.Conn.Unfetched), do: conn.params)
126124
}
127125
end
128126

127+
@sensitive ~w[cookie auth key secret token password credential private]
128+
129+
defp should_not_be_leaked?({key, _value}) do
130+
downcased = key |> String.downcase()
131+
132+
Enum.any?(@sensitive, &String.contains?(downcased, &1))
133+
end
134+
129135
defp remote_ip(conn = %Plug.Conn{}) do
130136
remote_ip =
131137
case Plug.Conn.get_req_header(conn, "x-forwarded-for") do

test/integrations/plug_test.exs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ defmodule ErrorTracker.Integrations.PlugTest do
3737
conn
3838
|> Plug.Conn.put_req_header("cookie", "who stole the cookie from the cookie jar ?")
3939
|> Plug.Conn.put_req_header("authorization", "Bearer plz-dont-leak-my-secrets")
40+
|> Plug.Conn.put_req_header("authentication-helper", "hunter42")
41+
|> Plug.Conn.put_req_header("important-token", "abcxyz")
42+
|> Plug.Conn.put_req_header("private-name", "Some call me... Tim")
43+
|> Plug.Conn.put_req_header("special-credential", "drink-your-ovaltine")
44+
|> Plug.Conn.put_req_header("special-key", "Begin Private Key; dontleakmeplz")
45+
|> Plug.Conn.put_req_header("special-secret", "Shh, it's a secret")
46+
|> Plug.Conn.put_req_header("special-password", "correct-horse-battery-staple")
4047
|> Plug.Conn.put_req_header("safe", "this can be safely stored in cleartext")
4148

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

5259
assert "cookie" not in header_names
5360
assert "authorization" not in header_names
61+
assert "authentication-helper" not in header_names
62+
assert "important-token" not in header_names
63+
assert "private-name" not in header_names
64+
assert "special-credential" not in header_names
65+
assert "special-key" not in header_names
66+
assert "special-password" not in header_names
67+
assert "special-secret" not in header_names
5468

5569
assert "safe" in header_names
70+
assert length(header_names) == 1
5671
end
5772
end

0 commit comments

Comments
 (0)