Safeguard
Vulnerability Analysis

Sentry SDK sensitive data exposure (CVE-2021-23727)

CVE-2021-23727 let sentry-sdk for Python leak OS environment variables into Sentry events, exposing secrets. Here's the impact, timeline, and fix.

Nayan Dey
Security Researcher
7 min read

Sentry is one of the most widely deployed error-tracking and application-monitoring platforms in the Python ecosystem, and its official SDK, sentry-sdk, ships inside thousands of Flask, Django, FastAPI, Celery, and RQ applications to automatically capture unhandled exceptions and forward them to Sentry's dashboard for triage. CVE-2021-23727 is a sensitive data exposure vulnerability in sentry-sdk for Python that affected versions prior to 1.1.0. Under default configuration, the SDK's request-extraction logic could capture and transmit the full WSGI environ dictionary — which, depending on the web server and deployment, may contain raw operating system environment variables — as part of the "Request" context attached to every captured event. In practice, this meant that database credentials, API keys, cloud provider tokens, session secrets, and other values commonly stored in environment variables could end up sitting in plaintext inside a Sentry project, visible to anyone with dashboard access and retained for as long as Sentry's data retention policy dictated.

Unlike a classic remote code execution bug, this is a confidentiality issue that turns a normal, well-intentioned observability tool into a passive secrets-exfiltration channel. Every unhandled exception, every crash report, every 500 error became a potential leak point — and because error monitoring is designed to run continuously in production, the exposure was persistent rather than a one-time event.

Affected Versions and Components

  • Package: sentry-sdk (Python), distributed via PyPI
  • Affected versions: All releases prior to 1.1.0
  • Fixed version: 1.1.0 and later
  • Affected integrations: The issue primarily impacted WSGI-based framework integrations — Flask, Django, Pyramid, Falcon, Bottle, and any custom WSGI middleware wrapping sentry_sdk.init() — because the RequestExtractor classes for these frameworks pulled data directly from the environ object passed by the web server. ASGI-only deployments and integrations that don't rely on the raw WSGI environ (e.g., some Celery/RQ task contexts) were less consistently affected, but any code path that serialized environ for error context was in scope.
  • Root cause: WSGI servers commonly merge CGI-style request metadata with the process's actual OS environment variables inside the environ dict passed to the application. The SDK treated this entire structure as generic "request" data rather than as a boundary that could contain secrets, and it did not apply the same scrubbing rules it used for headers, cookies, and form bodies.
  • Not required to trigger: No non-default configuration was needed. Even applications running with Sentry's send_default_pii setting left at its (secure-by-default) False value were still exposed, because the SDK did not classify the environment payload as PII in the first place — it was being sent as ordinary request/runtime context.

CVSS, EPSS, and KEV Context

CVE-2021-23727 is tracked in the National Vulnerability Database and the GitHub Security Advisory database (GHSA-g92j-vf7v-jhxr) as an information-disclosure weakness (CWE-215: Information Exposure Through Debug Information / CWE-200: Exposure of Sensitive Information). Severity scoring for this CVE varies noticeably between sources — NVD's CVSS 3.1 vector lands in the medium range (roughly 5.3), reflecting that exploitation depends on an attacker (or insider) already having some access to the Sentry project or its data pipeline, while some downstream vulnerability databases score it higher given the potential blast radius of leaked credentials. That scoring divergence is itself a useful signal for security teams: base CVSS scores frequently understate real business impact for secrets-exposure bugs, because the score models "who can trigger the bug" rather than "what happens once the data lands somewhere with weaker access controls than production."

There is no evidence this vulnerability was ever added to CISA's Known Exploited Vulnerabilities (KEV) catalog, and its EPSS (Exploit Prediction Scoring System) probability score is low, consistent with a bug that requires no active exploitation technique — it's a passive design flaw, not something an attacker "exploits" in the traditional sense. That combination (low EPSS, no KEV listing, but a real secrets-leak mechanism) is exactly the profile that causes this class of issue to get deprioritized in patch queues, even though the actual risk — standing exposure of production credentials — can be more damaging than many higher-scored RCE bugs if those credentials are reused elsewhere.

Timeline

  • 2019–2021: The affected RequestExtractor behavior shipped as part of sentry-sdk's WSGI framework integrations across multiple minor releases, with no scrubbing applied to the raw environ payload.
  • Early 2021: The behavior was identified and reported to the Sentry security team as a data-exposure risk affecting Python SDK users across supported WSGI frameworks.
  • May 2021: Sentry released sentry-sdk 1.1.0, which changed how request data is extracted and scrubbed for WSGI integrations, removing raw environment variables from the default captured payload.
  • June 2021: CVE-2021-23727 was published to the NVD, with a corresponding GitHub Security Advisory documenting affected versions and remediation guidance.
  • Ongoing: Because this is a "stale data" style vulnerability, the risk window doesn't close entirely at patch time — any secrets captured and stored in a Sentry project before the upgrade remain exposed inside that Sentry instance until they are found, redacted, and rotated.

Remediation Steps

  1. Upgrade immediately. Pin sentry-sdk to >=1.1.0 (current releases are well past this) in requirements.txt, pyproject.toml, or your lockfile, and redeploy every service that imports it — including background workers and batch jobs, not just web-facing apps.
  2. Audit existing Sentry data for leaked secrets. Search historical events in every affected Sentry project for environment-variable-shaped data (AWS_SECRET_ACCESS_KEY, DATABASE_URL, *_API_KEY, SECRET_KEY, etc.) in the "Request" or "Additional Data" tabs of captured events. Treat any hit as a confirmed exposure, not a hypothetical one.
  3. Rotate every credential found. If a database password, API token, or signing key shows up in a Sentry event, rotate it — regardless of how long it's been there or how "internal" the Sentry instance is. Assume it has been viewed by everyone with project access, including third-party support engineers if you use Sentry SaaS with elevated support access enabled.
  4. Purge or redact affected events. Use Sentry's data scrubbing / advanced data scrubbing rules (sensitive-fields, regex-based scrubbers) retroactively where supported, and delete events that can't be redacted, subject to your incident and audit requirements.
  5. Harden your Sentry configuration going forward. Explicitly configure before_send hooks to strip or redact known-sensitive keys before events leave your process, keep send_default_pii=False unless you have a specific and reviewed reason to change it, and enable server-side data scrubbing as defense in depth rather than relying solely on SDK-side behavior.
  6. Restrict Sentry project access and retention. Apply least-privilege roles to Sentry projects, shorten data retention where compliance allows, and treat your error-monitoring platform as a system that can hold secrets by accident — because, as this CVE demonstrates, it can.
  7. Extend the audit to other SDKs and languages. The underlying pattern — observability/telemetry tooling inadvertently capturing environment or request internals — isn't unique to Python. Review Sentry SDKs (and other APM/error-tracking SDKs) across your JavaScript, Ruby, Go, and Java services for similar default-scrubbing gaps.

How Safeguard Helps

Vulnerabilities like CVE-2021-23727 illustrate why a raw dependency scan isn't enough: knowing sentry-sdk is outdated is trivial, but knowing whether your specific application actually invokes the vulnerable WSGI request-extraction path — and whether it's running in a context where secrets live in os.environ — is what determines real risk and remediation priority. Safeguard's reachability analysis traces whether the vulnerable code paths in sentry-sdk are actually loaded and exercised in your deployed services, so teams can distinguish "technically present in the SBOM" from "actively exposing secrets in production." Griffin AI correlates that reachability signal with your environment-variable usage patterns and Sentry configuration to flag exactly which services warrant an urgent credential rotation versus a routine upgrade. Continuous SBOM generation and ingest keep every sentry-sdk version across your fleet — including in build artifacts and container images — visible in one place, closing the blind spots that let a fix like 1.1.0 sit unadopted for months. And when a fix is confirmed, Safeguard's auto-fix PRs open the dependency bump directly against your affected repositories, cutting the time between "vulnerability disclosed" and "patched in production" from weeks to hours.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.