Skip to content

Conn structs in stacktrace frame vars leak credentials via query_string, request_path and path_info #1195

Description

@timkonieczny

SDK version: 13.5.1 (master as of 2026-09-07); same on 13.3.0
Setup: Phoenix 1.7, Sentry.PlugCapture + Sentry.PlugContext with url_scrubber, body_scrubber and header_scrubber set

Summary

Follow-up to #477 / #1068. A %Plug.Conn{} in a stacktrace frame arg is scrubbed with Sentry.Scrubber.scrub/1 before being inspected into a frame var, but that scrub misses two things the request interface covers:

  • request_path and path_info are not in @scrubbable_conn_fields, so a credential in a path segment (/reset-password/:token) renders verbatim. The registered :url_scrubber never runs on this path.
  • query_string and query_params use the fixed :query_string / :params strategies, which only know the default keys (password, passwd, secret). put_conn_scrubber/1 cannot extend them.

scrub/2 takes per-call overrides, but PlugCapture calls scrub/1 with none, so there is no hook. An app can register scrubbers for every credential it mints and still ship a working reset token to Sentry when a tokenized request raises with the conn in the top frame.

Reproduction

token = "SEKRIT-TOKEN-VALUE"

Plug.Test.conn(:get, "/reset-password/#{token}")
|> Sentry.Scrubber.scrub()
|> inspect()
|> String.contains?(token)
#=> true (request_path, path_info)

Plug.Test.conn(:get, "/unsubscribe?token=#{token}")
|> Sentry.Scrubber.scrub()
|> inspect()
|> String.contains?(token)
#=> true (query_string, query_params), whatever scrubbers are registered

Since #1093 removed SDK-side truncation, the frame var is not cut short before the value either.

Suggestion

  1. Run the registered :url_scrubber (or its default) over request_path, path_info and query_string when scrubbing a conn.
  2. Let the registered conn scrubber reach the frame-var path, either by extending the key list the :query_string / :params strategies use, or by having PlugCapture pass overrides to scrub/2.

Workaround

A before_send that regex-redacts <key>=<value>, "<key>" => "<value>" and the app's tokenized path segments out of the rendered frame vars. Works, but it is the wrong layer.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions