Sentry: Your Error Tracker Is Leaking Secrets
Sentry captures stack traces and error context, which routinely includes API keys, database URLs, and session tokens. Public Sentry orgs leak these during error reporting. A recurring finding in application security penetration tests and vulnerability assessments.
What Sentry exposes by design
Sentry is an error tracking platform used by over 100,000 organizations. Every Sentry deployment, whether self-hosted or on-premise, has a set of API endpoints that were designed for internal diagnostics. The problem is that many of these endpoints are accessible without authentication on misconfigured instances, and they return the kind of information that turns a casual discovery into a serious compromise.
The most damaging endpoint is /api/0/internal/info/. On self-hosted Sentry instances running with default or misconfigured settings, this endpoint returns a JSON payload containing:
- SECRET_KEY: the Django secret key used to sign sessions, tokens, and CSRF protection
- Database connection URLs: full PostgreSQL connection strings including username, password, host, and database name
- Email/SMTP credentials: server, port, username, and password for the outbound mail configuration
- Redis connection strings: often with no authentication, used for caching and Celery task queues
- Kafka and Snuba configuration: internal service architecture details
Finding Sentry instances
The entry point is usually the DSN (Data Source Name) embedded in client-side JavaScript. Every Sentry integration requires a DSN that looks like this:
https://abc123def456@o123456.ingest.sentry.io/789012
For self-hosted instances, the DSN points to the organization's own domain:
https://abc123def456@sentry.company.com/2
This DSN is public by design. It is embedded in the JavaScript bundle shipped to every user's browser. It tells you exactly where the Sentry instance lives.
The enumeration chain
Once you have the Sentry hostname, the following endpoints are worth testing:
/api/0/internal/info/: the jackpot endpoint described above. Returns server configuration, secrets, and credentials./api/0/organizations/: lists all organizations on the instance. Each org entry includes slug, member count, project count, and feature flags./api/0/: the API root, which on some versions lists all available API endpoints and their documentation./api/0/internal/options/: returns the full System.Options configuration, including settings that control authentication, rate limiting, and feature flags.
Debug mode in production
Sentry is a Django application. When DEBUG = True (which should never be the case in production, but frequently is on hastily deployed self-hosted instances), every unhandled exception returns a full stack trace including:
- Local variables at every frame in the call stack
- The full Django settings module with all configuration values
- Database query logs
- File paths revealing the server's directory structure
We have seen self-hosted Sentry instances running in debug mode at organizations that handle medical records, financial data, and government contracts. The Sentry instance meant to track errors becomes the biggest error in their security posture.
What you can do with the SECRET_KEY
Django's SECRET_KEY is used to sign:
- Session cookies: forging a valid admin session cookie gives you authenticated access to the Sentry admin panel
- CSRF tokens: bypassing CSRF protection on every form and API endpoint
- Password reset tokens: generating valid password reset links for any user account
With the SECRET_KEY, you can craft a valid session cookie for the admin user:
from django.core.signing import Signer
from django.contrib.sessions.backends.db import SessionStore
# With the leaked SECRET_KEY, you can sign any session data
# and access the Sentry admin panel as any user
The database connection string
If the database connection URL is exposed and the PostgreSQL instance is reachable (common on cloud deployments where both Sentry and the database are in the same VPC with permissive security groups), you have direct database access. Sentry's database contains:
- Every error event, including request headers, cookies, and POST bodies from the monitored applications
- User accounts with hashed passwords
- API keys and integration tokens for connected services (Slack, Jira, GitHub, PagerDuty)
- Organization structure and access control configuration
Real-world prevalence
A Shodan search for "Sentry" "X-Sentry-Version" returns thousands of self-hosted instances. In our testing across bug bounty programs and authorized engagements, roughly 15% of self-hosted Sentry instances expose at least one sensitive API endpoint without authentication. The /api/0/internal/info/ endpoint is the most commonly exposed, likely because administrators don't realize it exists.
Defense
- Never run Sentry with DEBUG=True in production. This should be in every deployment checklist.
- Restrict /api/0/internal/ endpoints at the reverse proxy level. These endpoints should not be reachable from outside the server itself.
- Rotate SECRET_KEY if there is any chance it has been exposed. This will invalidate all existing sessions.
- Use Sentry's hosted offering (sentry.io) instead of self-hosting, unless you have the operational security maturity to maintain it.
- Network-segment the database so that PostgreSQL is only reachable from the Sentry application server, not from the broader network.
- Audit DSN exposure: your DSN is public, so ensure the Sentry instance behind it is properly hardened.
Want us to check your Sentry setup?
Our scanner detects this exact misconfiguration. plus dozens more across 38 platforms. Free website check available, no commitment required.
