Skip to content

fix(security): stop leaking internal error details from web API routes (CWE-209) - #1147

Closed
groupthinking wants to merge 3 commits into
mainfrom
claude/determined-maxwell-7p4us0
Closed

fix(security): stop leaking internal error details from web API routes (CWE-209)#1147
groupthinking wants to merge 3 commits into
mainfrom
claude/determined-maxwell-7p4us0

Conversation

@groupthinking

Copy link
Copy Markdown
Owner

Canonical issue

Closes #

Outcome

Next.js API routes no longer return raw exception strings (String(error), error.message, details: String(...)) to clients. Each handler now responds with a static, non-revealing message and logs the full error server-side via console.error. This removes a reconnaissance vector where backend hostnames, connection diagnostics, or stack context could leak to callers.

Scope

  • Included:
    • apps/web/src/app/api/agents/dispatch/route.ts, agents/status/route.ts — drop details: String(error) from 502 responses.
    • apps/web/src/app/api/extract-events/route.ts — replace leaked error.message with "Event extraction failed".
    • apps/web/src/app/api/jobs/[jobId]/route.ts — add server-side console.error, return generic "Failed to fetch job status".
    • apps/web/src/app/api/training/status/route.ts, training/trigger/route.ts — drop details: String(...); add console.error for the upload/trigger failure path so the detailed error is preserved internally without reaching the client.
    • apps/web/src/app/api/video/search/route.ts — replace leaked error.message with a generic message.
    • .jules/sentinel.md — records the vulnerability/learning/prevention note.
  • Explicitly excluded: backend (Python) error handlers; no changes to response status codes or success payloads.

Risk

  • Risk level: low
  • Failure mode: A client that previously parsed the leaked details/message string for diagnostics would now see only a generic message. No internal control flow depends on these strings.
  • Rollback: revert the branch; changes are isolated to catch-block response bodies.

Verification

List exact automated and manual checks, tied to the current head SHA.

  • Focused tests
  • Static review: confirmed no dangling references to removed bindings (message in extract-events, uploadError in training/trigger) and no remaining unused catch bindings.
  • Required CI
  • Review threads resolved

Note: the JS/TS toolchain (eslint/tsc) is not installed in the automation sandbox, so lint/typecheck was performed by static inspection only. CI should run the authoritative checks.

Production evidence

Not applicable at PR-open time — awaiting CI / Vercel preview on the current head.

Agent handoff

  • One canonical issue is linked
  • No competing PR implements the same issue
  • Acceptance criteria are satisfied
  • Required checks pass on the current head
  • Human decision is requested only for product, security, irreversible infrastructure, or production approval — this PR is left as draft pending human merge approval to the protected main branch.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NFDfJ3C6qTJ2Xda8SW93Pf


Generated by Claude Code

google-labs-jules Bot and others added 3 commits August 1, 2026 18:18
🚨 Severity: MEDIUM
💡 Vulnerability: Exposes raw backend error messages directly to the client
🎯 Impact: Could leak internal architecture details or timeout diagnostics
🔧 Fix: Log the detailed error internally and return a generic safe message
✅ Verification: Verified via linting and tests
🚨 Severity: MEDIUM
💡 Vulnerability: Exposes raw backend error messages directly to the client
🎯 Impact: Could leak internal architecture details or timeout diagnostics
🔧 Fix: Log the detailed error internally and return a generic safe message
✅ Verification: Verified via linting and tests
The prior error-leakage hardening removed 'details: String(uploadError)'
from the client response but left the caught 'uploadError' binding unused,
which trips strict no-unused-vars lint and drops the internal diagnostic.
Add a server-side console.error so the detailed error is preserved for
monitoring while the client still receives only a generic message.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NFDfJ3C6qTJ2Xda8SW93Pf
@vercel

vercel Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v0-uvai Ready Ready Preview, v0 Aug 1, 2026 6:37pm

@github-actions github-actions Bot added documentation Improvements or additions to documentation javascript Pull requests that update javascript code labels Aug 1, 2026
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • [‘architecture-gap’, ‘bug’, ‘ci-cd’, ‘ci/cd’, ‘copilot-rabbit’, ‘documentation’, ‘duplicate’, ‘enhancement’, ‘frontend’, ‘github_actions’, ‘good first issue’, ‘help wanted’, ‘high-priority’, ‘invalid’, ‘javascript’, ‘ml-model’, ‘needs-triage’, ‘pipeline-critical’, ‘placeholder-code’, ‘priority:high’, ‘python’, ‘python:uv’, ‘question’, ‘styling’, ‘tests’, ‘v0’]

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Repository UI (inherited), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5dcb0913-e0f7-4b2c-9704-1b7f79f0dcf7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA e5e91a3.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

Scanned Files

None

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

Agent Completion Truth Gate: BLOCKED

Reasons: invalid_payload

Machine-readable verdict
{
  "details": {
    "invalid_fields": [
      "issue.number",
      "policy.agent_login",
      "policy.run_id"
    ]
  },
  "reasons": [
    "invalid_payload"
  ],
  "verdict": "blocked"
}

Workflow evidence

@groupthinking groupthinking added frontend security and removed documentation Improvements or additions to documentation labels Aug 1, 2026 — with Claude

Copy link
Copy Markdown
Owner Author

Automated remediation status — HALTED(awaiting_human_governance)

The code change itself is sound: Vercel build deployed green (Ready), and validate / label / Canonical issue and evidence checks passed. I also fixed a lint/security regression the original commits introduced (an unused uploadError catch binding that had dropped internal logging — now restored via console.error). Labels added (security, javascript, frontend) so CodeRabbit's auto-review can run.

Two checks are red, and neither is a defect in this diff — both need a human decision, so I'm not force-passing them:

1. gitleaks (working tree) — pre-existing false positive, not caused by this PR.
The finding is uv.lock:5129, rule square-access-token, on:

hash = "sha256:eaaac4c9fdd5e9e8852dc778d2d7405897ec510f2a298071453e5e3a07914bb1"  # parso 0.8.7 sdist

That is a PyPI package integrity hash, not a secret. This PR does not touch uv.lock, so the gate is red on main too — it's a repo-wide .gitleaks.toml allowlist gap. Suggested fix (separate change, since editing secret-scan config doesn't belong in an error-leakage PR): add uv.lock to the [allowlist] paths (lockfiles carry only package hashes), or allowlist the square-access-token rule for *.lock files.

2. agent-completion/truth-gate + Agent completion enforcement — governance gate, needs a human.
blocked: invalid_payload, invalid fields issue.number, policy.agent_login, policy.run_id. This PR has no linked canonical issue and no trusted agent-provenance manifest. This gate exists precisely to require human-governed provenance, so I won't fabricate a run_id/agent_login to slip past it.

To move this forward, a maintainer needs to: link a canonical tracking issue (fills the Closes # / agent-lock manifest), and clear the uv.lock gitleaks false-positive repo-wide. The PR is intentionally left as draft pending merge approval to the protected main branch.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

Closing as a duplicate of #1145

This PR turned out to duplicate #1145 — both carry the identical 8-file error-leakage fix on the same head commit f856d46. #1145 is the canonical version: it's authored by Jules, is ready-for-review (not draft), and links the owning task 1121709532317009963. This branch happened to be sitting on the same two Sentinel commits, so opening #1147 created a competing PR for the same change.

Per the repo's "no competing PR implements the same issue" rule, I'm closing this in favor of #1145. The only delta this PR added — a console.error('Training upload/trigger error:', uploadError) in the training/trigger catch block (the branch #1145 modified but left without internal logging) — is carried over as a suggested follow-up comment on #1145.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend javascript Pull requests that update javascript code security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants