Sentry React is the official @sentry/react SDK for capturing errors, crashes, and performance data in React applications, and its biggest security risk is not a CVE but the data you accidentally send to it. Because the SDK runs in the browser and serializes exceptions, breadcrumbs, and network events, a careless setup can ship access tokens, session cookies, or personal data straight into your error backend. Getting Sentry React right is mostly about controlling what leaves the client.
This guide walks through the parts of the integration that actually matter for security: the DSN, PII scrubbing, source maps, and keeping the SDK itself patched.
What the Sentry React SDK actually sends
When an error is thrown, @sentry/react builds an event containing the stack trace, a list of breadcrumbs (console logs, clicks, XHR/fetch calls), the current URL, and any context you attach. Breadcrumbs are the sneaky part. If your app logs a request body or a URL with a query string like ?token=abcdef, that string becomes a breadcrumb and gets transmitted.
A minimal, reasonably safe initialization looks like this:
import * as Sentry from "@sentry/react";
Sentry.init({
dsn: import.meta.env.VITE_SENTRY_DSN,
environment: import.meta.env.MODE,
sendDefaultPii: false,
tracesSampleRate: 0.1,
beforeSend(event) {
// drop events from local dev
if (event.environment === "development") return null;
return event;
},
});
The sendDefaultPii: false flag is the default, but set it explicitly so a future refactor does not silently flip it on.
Is the DSN a secret?
The Sentry DSN embedded in a React bundle is public by design. Anyone can read it in the shipped JavaScript, so treat it as an identifier, not a credential. What that means in practice: a DSN cannot be used to read your errors, only to send events to your project. The realistic abuse is someone flooding your project with junk events to burn quota.
Mitigate that with rate limiting and inbound filters in the Sentry project settings, and by scoping the DSN to a single project. Do not put your Sentry auth token (the one used by the CLI to upload source maps) in client code. That token is a real secret and belongs only in CI environment variables.
Scrub PII before it leaves the browser
The beforeSend and beforeBreadcrumb hooks are your last line of defense. Use them to strip anything sensitive:
Sentry.init({
dsn: import.meta.env.VITE_SENTRY_DSN,
beforeBreadcrumb(breadcrumb) {
if (breadcrumb.category === "xhr" || breadcrumb.category === "fetch") {
if (breadcrumb.data?.url?.includes("token=")) {
breadcrumb.data.url = "[redacted]";
}
}
return breadcrumb;
},
beforeSend(event) {
if (event.request?.headers) {
delete event.request.headers["Authorization"];
delete event.request.headers["Cookie"];
}
return event;
},
});
Sentry also runs server-side data scrubbing on common patterns (credit card numbers, keys named password or secret), but do not rely on it alone. Client-side scrubbing means the data never leaves the user's machine in the first place, which is the stronger guarantee for privacy regimes like GDPR.
Source maps: helpful for you, helpful for attackers
Readable stack traces in Sentry require source maps. The mistake teams make is deploying those source maps to the public web root alongside the bundle, which lets anyone reconstruct your original source. Upload source maps directly to Sentry with the CLI or bundler plugin, then delete them from the deploy artifact:
sentry-cli sourcemaps upload --release "$RELEASE" ./dist
# then ensure ./dist/*.map is not served publicly
If you use the Vite or Webpack Sentry plugin, set the option to delete source maps after upload. Serving .map files publicly is not catastrophic, but it removes a layer of obscurity around your business logic and can expose commented-out endpoints or feature flags.
Keep the SDK and its dependencies patched
@sentry/react pulls in a small tree of @sentry/* packages. Browser SDKs are widely deployed, which makes any vulnerability in them high-impact, so track updates. Pin a recent 8.x or 9.x line and update on a regular cadence rather than letting it drift for a year. An SCA tool such as Safeguard can flag when a transitive Sentry dependency picks up a known advisory, which matters because you rarely install those sub-packages directly.
Run npm audit or your scanner on every build, and treat the Sentry SDK like any other third-party runtime dependency: it executes in your users' browsers, so its supply chain is your supply chain. If you want the deeper mechanics of that, our guide to dependencies in programming covers why transitive packages deserve the same scrutiny as direct ones.
Content Security Policy and Sentry
If you enforce a Content Security Policy, remember Sentry needs a connect-src entry for your ingest domain (either *.sentry.io or your self-hosted host). Do not open connect-src to a wildcard just to make Sentry work. Add the specific ingest host and nothing more. A tight CSP is one of the cheapest defenses against data exfiltration through injected scripts, and it pairs well with the error monitoring Sentry provides.
FAQ
Is the Sentry React DSN safe to expose in client code?
Yes. The DSN is meant to be public and only permits sending events to your project, not reading them. Protect quota with rate limits and inbound filters, and never confuse the DSN with the auth token used for source map uploads, which must stay secret.
Does Sentry React send personal data by default?
With sendDefaultPii off (the default), it will not attach IP addresses or user identifiers automatically, but breadcrumbs can still capture sensitive URLs or request data. Use beforeSend and beforeBreadcrumb to scrub anything sensitive before transmission.
Should I commit source maps to my deployment?
No. Upload them to Sentry during CI so stack traces stay readable in the dashboard, then remove the .map files from the public deploy so they are not downloadable by anyone visiting your site.
How often should I update @sentry/react?
Treat it like any runtime dependency and update on a regular cadence, at minimum whenever a security advisory affects the @sentry/* tree. Since the SDK runs in users' browsers, an unpatched flaw there is client-side exposure.