From 36e2d4334e55fd32e6fa1458d59ee8698dd379b7 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Sat, 23 May 2026 17:57:06 +0200 Subject: [PATCH] Sentry: Scrub secrets from event details --- src/pretix/sentry.py | 37 ++++++++++++++++++++++++++++++++++++- src/pretix/settings.py | 6 +++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/pretix/sentry.py b/src/pretix/sentry.py index 9e40e8ce3f..fb74faaf51 100644 --- a/src/pretix/sentry.py +++ b/src/pretix/sentry.py @@ -19,12 +19,18 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # +import re +import typing import weakref from celery.exceptions import Retry from sentry_sdk import Hub from sentry_sdk.integrations import django as djangosentry -from sentry_sdk.utils import capture_internal_exceptions +from sentry_sdk.scrubber import EventScrubber +from sentry_sdk.utils import AnnotatedValue, capture_internal_exceptions + +if typing.TYPE_CHECKING: + from sentry_sdk._types import Event def _make_event_processor(weak_request, integration): @@ -96,3 +102,32 @@ def setup_custom_filters(): hub = Hub.current with hub.configure_scope() as scope: scope.add_event_processor(ignore_retry) + + +class PretixEventScrubber(EventScrubber): + secret_re = re.compile( + '.*(pretixsecret|ramiiosecret|PRIVATE KEY|://[^/@:]*:[^/@:]+@).*', + re.IGNORECASE + ) + + def scrub_dict(self, d: object) -> None: + if not isinstance(d, dict): + return + + super().scrub_dict(d) + self._scrub_dict_for_known_secrets(d) + + def _scrub_dict_for_known_secrets(self, d: dict): + for k, v in d.items(): + if isinstance(v, str) and self.secret_re.match(v): + d[k] = AnnotatedValue.substituted_because_contains_sensitive_data() + + def scrub_exception(self, event: "Event") -> None: + with capture_internal_exceptions(): + if "exception" in event: + self.scrub_dict(event["exception"]) + + def scrub_event(self, event: "Event") -> None: + super().scrub_event(event) + self.scrub_exception(event) + print(event) diff --git a/src/pretix/settings.py b/src/pretix/settings.py index 646972af7e..466096636e 100644 --- a/src/pretix/settings.py +++ b/src/pretix/settings.py @@ -704,9 +704,9 @@ if config.has_option('sentry', 'dsn') and not any(c in sys.argv for c in ('shell from sentry_sdk.integrations.logging import ( LoggingIntegration, ignore_logger, ) - from sentry_sdk.scrubber import EventScrubber, DEFAULT_DENYLIST + from sentry_sdk.scrubber import DEFAULT_DENYLIST - from .sentry import PretixSentryIntegration, setup_custom_filters + from .sentry import PretixSentryIntegration, PretixEventScrubber, setup_custom_filters SENTRY_TOKEN = config.get('sentry', 'traces_sample_token', fallback='') pretix_denylist = DEFAULT_DENYLIST + [ @@ -739,7 +739,7 @@ if config.has_option('sentry', 'dsn') and not any(c in sys.argv for c in ('shell traces_sampler=traces_sampler, environment=urlparse(SITE_URL).netloc, release=__version__, - event_scrubber=EventScrubber(denylist=pretix_denylist, recursive=True), + event_scrubber=PretixEventScrubber(denylist=pretix_denylist, recursive=True), send_default_pii=False, propagate_traces=False, # see https://github.com/getsentry/sentry-python/issues/1717 )