Skip to content

Commit 42d3489

Browse files
committed
cookie scrubbing
1 parent 2ac6121 commit 42d3489

File tree

3 files changed

+63
-5
lines changed

3 files changed

+63
-5
lines changed

lib/sentry/plug.ex

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,15 @@ if Code.ensure_loaded?(Plug) do
6868
6969
use Sentry.Plug, header_scrubber: {MyModule, :scrub_headers}
7070
71-
To configure scrubbing body and header data, we can set both configuration keys:
71+
### Cookie Scrubber
7272
73-
use Sentry.Plug, header_scrubber: &scrub_headers/1, body_scrubber: &scrub_params/1
73+
By default Sentry will scrub all cookies before sending events.
74+
It can be configured similarly to the headers scrubber, but is configured with the `:cookie_scrubber` key.
75+
76+
To configure scrubbing, we can set all configuration keys:
77+
78+
use Sentry.Plug, header_scrubber: &scrub_headers/1,
79+
body_scrubber: &scrub_params/1, cookie_scrubber: &scrub_cookies/1
7480
7581
### Including Request Identifiers
7682
@@ -89,6 +95,7 @@ if Code.ensure_loaded?(Plug) do
8995
body_scrubber = Keyword.get(env, :body_scrubber, {__MODULE__, :default_body_scrubber})
9096

9197
header_scrubber = Keyword.get(env, :header_scrubber, {__MODULE__, :default_header_scrubber})
98+
cookie_scrubber = Keyword.get(env, :cookie_scrubber, {__MODULE__, :default_cookie_scrubber})
9299

93100
request_id_header = Keyword.get(env, :request_id_header)
94101

@@ -109,6 +116,7 @@ if Code.ensure_loaded?(Plug) do
109116
opts = [
110117
body_scrubber: unquote(body_scrubber),
111118
header_scrubber: unquote(header_scrubber),
119+
cookie_scrubber: unquote(cookie_scrubber),
112120
request_id_header: unquote(request_id_header)
113121
]
114122

@@ -130,6 +138,7 @@ if Code.ensure_loaded?(Plug) do
130138
def build_request_interface_data(%Plug.Conn{} = conn, opts) do
131139
body_scrubber = Keyword.get(opts, :body_scrubber)
132140
header_scrubber = Keyword.get(opts, :header_scrubber)
141+
cookie_scrubber = Keyword.get(opts, :cookie_scrubber)
133142
request_id = Keyword.get(opts, :request_id_header) || @default_plug_request_id_header
134143

135144
conn =
@@ -141,7 +150,7 @@ if Code.ensure_loaded?(Plug) do
141150
method: conn.method,
142151
data: handle_data(conn, body_scrubber),
143152
query_string: conn.query_string,
144-
cookies: conn.req_cookies,
153+
cookies: handle_data(conn, cookie_scrubber),
145154
headers: handle_data(conn, header_scrubber),
146155
env: %{
147156
"REMOTE_ADDR" => remote_address(conn.remote_ip),
@@ -171,6 +180,11 @@ if Code.ensure_loaded?(Plug) do
171180
fun.(conn)
172181
end
173182

183+
@spec default_cookie_scrubber(Plug.Conn.t()) :: map()
184+
def default_cookie_scrubber(_conn) do
185+
%{}
186+
end
187+
174188
@spec default_header_scrubber(Plug.Conn.t()) :: map()
175189
def default_header_scrubber(conn) do
176190
Enum.into(conn.req_headers, %{})

test/plug_test.exs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,45 @@ defmodule Sentry.PlugTest do
169169
|> Sentry.ExampleApp.call([])
170170
end)
171171
end
172+
173+
test "default cookie scrubbing" do
174+
bypass = Bypass.open()
175+
176+
Bypass.expect(bypass, fn conn ->
177+
{:ok, body, conn} = Plug.Conn.read_body(conn)
178+
json = Poison.decode!(body)
179+
assert json["request"]["cookies"] == %{}
180+
Plug.Conn.resp(conn, 200, ~s<{"id": "340"}>)
181+
end)
182+
183+
modify_env(:sentry, dsn: "http://public:secret@localhost:#{bypass.port}/1")
184+
185+
assert_raise(RuntimeError, "Error", fn ->
186+
conn(:get, "/error_route")
187+
|> put_req_cookie("cookie_key", "cookie_value")
188+
|> Sentry.ExampleApp.call([])
189+
end)
190+
end
191+
192+
test "custom cookie scrubbing" do
193+
conn =
194+
conn(:get, "/error_route")
195+
|> put_req_cookie("cookie_key", "cookie_value")
196+
|> put_req_cookie("cookie_key2", "cookie_value2")
197+
|> put_req_cookie("secret", "value")
198+
199+
request_data =
200+
Sentry.Plug.build_request_interface_data(
201+
conn,
202+
cookie_scrubber: fn(conn) ->
203+
conn.req_cookies
204+
|> Map.take(["cookie_key", "cookie_key2"])
205+
end
206+
)
207+
208+
assert request_data[:cookies] == %{
209+
"cookie_key" => "cookie_value",
210+
"cookie_key2" => "cookie_value2"
211+
}
212+
end
172213
end

test/support/test_plug.ex

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
defmodule Sentry.ExampleApp do
22
use Plug.Router
33
use Plug.ErrorHandler
4-
use Sentry.Plug, request_id_header: "x-request-id"
5-
4+
use Sentry.Plug, request_id_header: "x-request-id", cookie_scrubber: &Sentry.ExampleApp.allow_all_cookie_scrubber/1
65

76
plug Plug.Parsers, parsers: [:multipart]
87
plug Plug.RequestId
@@ -31,4 +30,8 @@ defmodule Sentry.ExampleApp do
3130
_ = conn
3231
raise RuntimeError, "Error"
3332
end
33+
34+
def all_cookie_scrubber(conn) do
35+
conn.req_cookies
36+
end
3437
end

0 commit comments

Comments
 (0)