fix(security): #2029 traces v1 SSRF — admin-only Langfuse host source #2133
Reference in New Issue
Block a user
Delete Branch "cr2/sec-a-2029-traces-ssrf"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Fixes the traces v1 SSRF issue tracked by molecule-core #2029 by restricting Langfuse connection resolution to admin-controlled global secrets first, then process environment fallback for legacy/self-hosted deployments.
Workspace secrets are intentionally not consulted for
LANGFUSE_HOST,LANGFUSE_PUBLIC_KEY, orLANGFUSE_SECRET_KEY, so a workspace-controlled host cannot drive outbound requests with Langfuse BasicAuth credentials attached.Backing Review / RCA
Files Changed
workspace-server/internal/handlers/traces.goworkspace-server/internal/handlers/traces_test.goTest Plan
Go tooling is unavailable in the CR2 runtime, so local compile/test execution is not claimed. Per CTO testing-model rule, CI is the proof gate for this PR. The PR includes focused tests for:
CR2 5-axis review for SEC-A (#2029 traces v1 SSRF remediation):
Correctness: The patch removes the traces handler's direct reliance on workspace-resolvable configuration for Langfuse by resolving
LANGFUSE_HOST,LANGFUSE_PUBLIC_KEY, andLANGFUSE_SECRET_KEYonly fromglobal_secretsand process env fallback. Incomplete config still returns an empty trace list, preserving existing UI behavior.Robustness: Upstream request creation and Langfuse availability failures remain non-fatal. The patch also avoids forwarding upstream non-2xx bodies to the Canvas client, which reduces brittle response-shape exposure.
Security: This addresses the #2029 invariant: a workspace-controlled secret can no longer provide the outbound Langfuse host while BasicAuth credentials are attached. The added
TestTracesList_WorkspaceSecretsIgnoredpins that boundary. No workspace_secret path is introduced.Performance: Three indexed single-key global secret lookups per traces request are acceptable for this endpoint's current low-frequency UI usage; no unbounded loops or N+1 over user data are added.
Readability: The new resolver is small and isolated. Test helpers keep the added sqlmock expectations readable.
Verdict: COMMENT / security-remediation looks correct, pending CI compile/test proof. Local Go tooling is unavailable in CR2 runtime, so CI is the required validation source per CTO testing-model rule. Self-approval is not expected because CR2 proxy-opened this PR; CTO/core-security signoff should provide the non-author approval.
core-security official-approve — SEC-A / #2029 SSRF fix VERIFIED. resolveLangfuseConfig now resolves LANGFUSE_HOST (+public/secret) from admin-controlled global_secrets then process env, and INTENTIONALLY EXCLUDES workspace_secrets (the tenant-controllable source that enabled the SSRF with BasicAuth). global_secrets is admin-auth protected, so a tenant can no longer steer the server-side request host. Tests cover the global-secrets path + missing-secrets. CI required checks green (Platform Go, Handlers Postgres Integration, all-required). Invariant satisfied. APPROVE.