Skip to content

Commit 02298cb

Browse files
authored
security: close telemetry leak in preconnectAnthropicApi startup path (#1253)
🔒 Security Discovery: Un-gated outbound connection bypasses privacy controls Summary ------- preconnectAnthropicApi() unconditionally sends a TCP+TLS handshake to api.anthropic.com on every ccb startup — even when the user has explicitly disabled all non-essential traffic via CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 or DISABLE_TELEMETRY=1. This is the LAST un-gated outbound connection in the entire startup path. Every other telemetry sink (Sentry, Langfuse, OpenTelemetry, GrowthBook, 1P Event Logger, Datadog, BigQuery, etc.) already respects the privacyLevel module's isEssentialTrafficOnly() gate. This one did not. Impact ------ While the preconnect is a HEAD request with no payload, the connection itself leaks the client's IP address and session timing to Anthropic's infrastructure. For privacy-conscious users and enterprise deployments that have disabled telemetry, this constitutes an unexpected data leak. Fix --- Add isEssentialTrafficOnly() check at the function entry, consistent with every other privacy-gated code path in the codebase. The privacyLevel module is already imported by init.ts and 12+ other modules — no new dependencies. Verification ------------ Reproduced and verified via strace on Linux (aarch64): # Before fix $ strace -f -e connect ccb -p <<< 'hello' connect(16, sin_addr=inet_addr("160.79.104.10"), sin_port=htons(443)) = 0 # ↑ connector to api.anthropic.com despite CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 # After fix $ strace -f -e connect ccb -p <<< 'hello' # ↑ zero remote TCP connections — all traffic to localhost only Changes: 1 file, +5 lines (import + gate)
1 parent b2b1981 commit 02298cb

1 file changed

Lines changed: 5 additions & 0 deletions

File tree

src/utils/apiPreconnect.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@
2525

2626
import { getOauthConfig } from '../constants/oauth.js'
2727
import { isEnvTruthy } from './envUtils.js'
28+
import { isEssentialTrafficOnly } from './privacyLevel.js'
2829

2930
let fired = false
3031

3132
export function preconnectAnthropicApi(): void {
3233
if (fired) return
3334
fired = true
3435

36+
// Also skip when non-essential traffic is disabled via
37+
// CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC / DISABLE_TELEMETRY / proxy env.
38+
if (isEssentialTrafficOnly()) return
39+
3540
// Skip if using a cloud provider — different endpoint + auth
3641
if (
3742
isEnvTruthy(process.env.CLAUDE_CODE_USE_BEDROCK) ||

0 commit comments

Comments
 (0)