Why This Matters
In June 2026, security researchers confirmed that publicly exposed Sentry DSN (Data Source Name) keys embedded in AI coding assistants — Claude Code, Cursor, and OpenAI's Codex — create a practical exploitation vector. An attacker who extracts the embedded key can intercept error telemetry, inject crafted payloads, and potentially manipulate AI agent behavior. This isn't theoretical. The keys are discoverable through routine reconnaissance, and the attack requires minimal sophistication.
When these DSNs are exposed, attackers can:
- Intercept error telemetry containing code snippets, file paths, and environment variables
- Inject false error reports that could trigger specific agent behaviors
- Harvest authentication tokens leaked through stack traces
- Map internal infrastructure through exposed service configurations
Chris's Take
Any tool that can see your code, file names, or settings is sending out really private information. The problem with AI agents is that they can act on that information without authenticating the source. Telemetry data may be hacked and fed malicious content knowing the AI agent will act upon it — wreaking havoc on any project your AI agent has access to.
Prerequisites
Before proceeding, ensure you have:
- Access to your AI coding tool's installation directory (Claude Code, Cursor, or VS Code with Codex extensions)
- Basic command-line proficiency (Bash, PowerShell, or Zsh)
- Network traffic analysis capability — mitmproxy or Burp Suite
- Administrative privileges on your development machine
- Node.js 18+ for running detection scripts
- Semgrep and Gitleaks for CI/CD integration (Steps 4–5)
Step 1: Locate Exposed Sentry DSNs
Sentry DSNs follow a predictable format. Start by scanning your AI tool's installation files directly.
For Electron-based apps (Cursor, Claude Code), unpack the ASAR archive first:
# Install asar tool globally
npm install -g @electron/asar
# Extract the archive (adjust path for your OS)
# macOS
asar extract /Applications/Cursor.app/Contents/Resources/app.asar ./app_extracted/
# Linux
asar extract /opt/Cursor/resources/app.asar ./app_extracted/
# Search extracted contents
grep -r -E "ingest\.sentry\.io" ./app_extracted/
For a broader scan across your codebase and commit history using Gitleaks:
# Install Gitleaks
brew install gitleaks
# Scan repository including history
gitleaks detect --source . --verbose --report-path sentry-exposure-report.json
# Custom Sentry DSN rule
cat << 'EOF' > .gitleaks.toml
[[rules]]
id = "sentry-dsn"
description = "Sentry DSN Key"
regex = '''https://[a-f0-9]{32}@[a-z0-9]+\.ingest\.sentry\.io/[0-9]+'''
tags = ["sentry", "api-key"]
EOF
gitleaks detect --config .gitleaks.toml --source .
A vulnerable DSN looks like this:
https://abc123def456abc123def456abc123de@o123456.ingest.sentry.io/7891011
Step 2: Verify the DSN Is Actively Exploitable
Finding a DSN isn't enough — you need to confirm it accepts external submissions. This script does that without sending any real data:
// sentry-dsn-tester.js
const https = require('https');
const testDSN = process.argv[2];
if (!testDSN) {
console.error('Usage: node sentry-dsn-tester.js <DSN>');
process.exit(1);
}
const dsnRegex = /https:\/\/([a-f0-9]+)@([^/]+)\/(\d+)/;
const match = testDSN.match(dsnRegex);
if (!match) { console.error('Invalid DSN format'); process.exit(1); }
const [, publicKey, host, projectId] = match;
const envelope = `{"event_id":"${'a'.repeat(32)}","sent_at":"${new Date().toISOString()}","dsn":"${testDSN}"}
{"type":"event"}
{"message":"DSN exposure test - AI Dev Defense audit","level":"info","platform":"javascript"}`;
const req = https.request({
hostname: host, port: 443,
path: `/api/${projectId}/envelope/`,
method: 'POST',
headers: {
'Content-Type': 'application/x-sentry-envelope',
'X-Sentry-Auth': `Sentry sentry_key=${publicKey}, sentry_version=7`
}
}, (res) => {
console.log(`[!] DSN Status: ${res.statusCode === 200 ? 'VULNERABLE' : 'Protected/invalid'}`);
console.log(`[*] Response: ${res.statusCode}`);
});
req.on('error', (e) => console.error(`[X] ${e.message}`));
req.write(envelope);
req.end();
node sentry-dsn-tester.js "https://abc123...@o123456.ingest.sentry.io/7891011"
Step 3: Monitor Outbound Telemetry Traffic
Before blocking anything, understand what your tools are actually transmitting. Set up traffic interception and observe the payloads — you may find stack traces containing code snippets, file paths revealing project structure, environment variables, and session tokens.
# mitmproxy — capture Sentry traffic only
mitmproxy --mode regular --listen-port 8080 \
--set block_global=false \
--filter "~d sentry.io"
Configure your system proxy to route through mitmproxy, launch your AI coding tool, and observe the payloads before you block anything.
Chris's Take
Most teams think finding and rotating the DSN is the win, but they miss that Sentry intentionally makes those keys public. The real problem is AI coding agents pulling the error events and treating them as trusted instructions they can act on with real privileges on your machine. So the right order in my opinion is to first inspect what's actually being sent and how the agent consumes it, lock down the agent so untrusted events can't turn into commands, and only then rotate the key. A brand-new public DSN can still be abused the exact same way.
Step 4: Immediate Containment
Option A — Network-level blocking (most durable)
Network blocking persists across app updates, unlike client-side patches. Use application-specific rules where possible rather than global DNS blocking — you don't want to break legitimate Sentry usage in your own services.
# /etc/hosts — immediate blocking (macOS/Linux)
127.0.0.1 o123456.ingest.sentry.io
127.0.0.1 sentry.io
# iptables (Linux)
sudo iptables -A OUTPUT -d sentry.io -j DROP
On macOS, Little Snitch or Lulu allow per-application rules — block the AI coding tool specifically while leaving your own Sentry integrations intact. On Windows, GlassWire or Portmaster provide the same capability.
Option B — Key rotation
If you have access to the Sentry project, rotate the key immediately. But do this in addition to network controls — not instead of them.
# Sentry CLI — verify and rotate
sentry-cli projects list --org your-org
# Then in Sentry UI:
# Settings > Projects > [Project] > Client Keys
# Generate New Key, then disable the old one
# Verify the new key works
sentry-cli send-event --dsn "NEW_DSN_HERE" -m "Key rotation test"
Step 5: Runtime Hardening — Scrub Before It Leaves
If you control the Sentry integration in your own code or tooling, harden the configuration to prevent sensitive context from being transmitted in the first place:
# secure_sentry_config.py
import sentry_sdk
sentry_sdk.init(
dsn=get_sentry_dsn(), # from env/vault — never hardcoded
send_default_pii=False,
before_breadcrumb=filter_sensitive_breadcrumbs,
before_send=scrub_sensitive_data,
attach_stacktrace=False,
include_source_context=False, # critical for AI tools
include_local_variables=False,
)
def filter_sensitive_breadcrumbs(breadcrumb, hint):
"""Remove breadcrumbs containing AI prompts or code context."""
sensitive_categories = ['ai.prompt', 'ai.completion', 'code.context']
if breadcrumb.get('category') in sensitive_categories:
return None
message = breadcrumb.get('message', '')
if any(term in message.lower() for term in ['prompt', 'instruction', 'api_key']):
return None
return breadcrumb
def scrub_sensitive_data(event, hint):
"""Scrub AI-specific sensitive data from Sentry events."""
if 'extra' in event:
keys_to_remove = [k for k in event['extra']
if any(s in k.lower() for s in
['prompt', 'context', 'instruction', 'code'])]
for key in keys_to_remove:
del event['extra'][key]
return event
Step 6: Continuous Monitoring — Bake It Into Your Pipeline
One-time detection isn't enough. Add Semgrep rules to your CI/CD pipeline so exposed DSNs get caught before they ship:
# .semgrep/sentry-security.yaml
rules:
- id: hardcoded-sentry-dsn
patterns:
- pattern-regex: 'https://[a-f0-9]{32}@\w+\.ingest\.sentry\.io/\d+'
message: "Hardcoded Sentry DSN detected. Use environment variables."
severity: ERROR
languages: [generic]
- id: sentry-source-context
patterns:
- pattern: sentry_sdk.init(..., include_source_context=True, ...)
message: "Source context transmission may expose proprietary code."
severity: WARNING
languages: [python]
# .github/workflows/sentry-security.yml
name: Sentry Security Scan
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Gitleaks Scan
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Semgrep Sentry Rules
uses: returntocorp/semgrep-action@v1
with:
config: .semgrep/sentry-security.yaml
Common Pitfalls
Rotating the key without updating all instances. Multiple AI tools may share the same Sentry project. Document every integration point before rotation and update them simultaneously.
Blocking Sentry entirely. Complete blocking breaks legitimate error monitoring in your own services. Use application-specific firewall rules, not global DNS blocking.
Assuming client-side removal is permanent. Patches to Electron app bundles get overwritten on every update. Network-level controls and CI pipeline checks are the durable solution.
Focusing on the key and ignoring the telemetry content. Before blocking, capture and review what was already transmitted. The key is one problem; the data already sent is another.
Chris's Take
Previously injected events could essentially be cached and pulled again later, so actively scrubbing or archiving old Sentry events is something that should be done — not just rotating the key and moving on.
Summary & Next Steps
A public Sentry key embedded in an AI coding assistant is a practical attack surface, not a theoretical one. The fix isn't complicated, but it requires doing more than just rotating the key. Network-level controls, scrubbed telemetry configuration, and CI pipeline rules together close the gap in a way that survives app updates.
This week:
- Run the ASAR extraction + DSN grep against your AI tools
- Use mitmproxy to understand what's actually being transmitted before you block it
- Implement network-level blocking for the AI tool specifically
- Add the Semgrep rules to your CI pipeline
- If you control the Sentry integration, set
include_source_context=Falseandsend_default_pii=False
The broader point: AI coding assistants operate with significant trust and access to proprietary code. They deserve the same security scrutiny you apply to any other tool in your supply chain.