fix(slack): remove unused unsafe auth fetch helper#98495
Conversation
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. This PR is useful and the final deletion shape looks correct, but it is no longer the best landing candidate because an open current-main-based replacement carries the same Slack helper/test removal, preserves contributor credit, is mergeable, and has passing proof checks. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Canonical path: Close this source PR and use #99944 as the canonical current-main landing path for the same cleanup, with contributor credit preserved there. So I’m closing this here and keeping the remaining discussion on #99944. Review detailsBest possible solution: Close this source PR and use #99944 as the canonical current-main landing path for the same cleanup, with contributor credit preserved there. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows current main's private helper validates the first Slack URL, then follows redirected HTTPS URLs with Is this the best way to solve the issue? Yes for the end state: deleting the private unused helper is narrower than maintaining a second redirect loop, and the same end state is now better handled by the current-main replacement PR. Security review: Security review cleared: The diff removes an unused token-bearing network helper and helper-only tests, with no dependency, workflow, package, or secret-handling expansion. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against d6ed2c392c1e. |
94316d8 to
38b2182
Compare
|
@clawsweeper re-review Updated the Real behavior proof section with non-mocked evidence: a real local HTTPS server + production undici dispatcher (globalThis.fetch is not replaced), with the server logging each hop it actually receives. |
|
🦞🧹 I asked ClawSweeper to review this item again. |
…t (SSRF) fetchWithSlackAuth only validated the initial URL via assertSlackFileUrl but then handed redirect handling to fetch redirect-follow, which follows up to 20 hops to any HTTPS URL. A redirect from a Slack host to an arbitrary HTTPS endpoint (internal service, attacker host) bypassed the SSRF guard entirely. Rewrite the redirect handling as a manual-redirect loop that re-validates every hop against isSlackHostname (Slack allowlist) and requires HTTPS, throws on a non-Slack or non-HTTPS target, and strips Authorization on cross-origin hops. Bounded to MAX_REDIRECTS=5. Non-redirect (2xx/4xx/5xx) and missing/malformed Location responses are returned unchanged, preserving the existing contract. Add SSRF regression tests: redirect to a non-Slack host throws, redirect to non-HTTPS throws. Update existing redirect tests to expect manual redirect on the second hop (the loop no longer hands off to follow). Co-Authored-By: Claude <[email protected]>
38b2182 to
a0eb4de
Compare
|
Land-ready proof for head Maintainer work:
Verification:
Known proof gap: no live Slack workspace run. The removed helper had no production callers and was not exported through |
|
🦞✅ Reason: structured ClawSweeper close marker: close-required (sha=c593263aaa747bc6bf05529c54a8421645388b4c) Closed:
|
|
Landed the reviewed fix as #99944 in commit 706443c: 706443c. The original redirect gap was real. Full review showed We first updated this fork branch, but GitHub's maintainer-edit API can append a verified commit without rewriting branch ancestry. The repository merge guard required a current-main lineage, so #99944 recreated the same reviewed two-file tree as one current-main maintainer commit. Thank you @miorbnli for finding and proving the issue. Closing this PR as superseded by the landed canonical fix. |
What Problem This Solves
fetchWithSlackAuthduplicated Slack redirect policy inextensions/slack/src/monitor/media.ts, contained an unsafe automatic-redirect path, and had no production callers. It was also not exported through the Slack plugin API, so retaining and expanding it would create a second network policy implementation without protecting any runtime behavior.Why This Change Was Made
The maintainer rewrite removes the unused helper and its helper-only tests instead of adding another redirect loop. Active Slack downloads already use
createSlackMediaRequest+createSlackMediaFetch+saveRemoteMedia, which delegates redirect handling, DNS pinning, authorization stripping, and SSRF policy enforcement to the shared guarded-fetch path.This keeps one canonical implementation and removes the unsafe future footgun entirely.
User Impact
No current runtime behavior changes: the removed helper had no production caller and was not part of
extensions/slack/api.ts. Slack private-file and forwarded-image downloads continue through the existing guarded media path.Evidence
fetchWithSlackAuthreferences remain; before removal, its dedicated tests were the only callers.extensions/slack/api.tsdoes not export the helper.resolveSlackMediaand forwarded attachment downloads continue throughsaveRemoteMediawith Slack hostname policy and manual redirect handling.tbx_01kwpdqh65849veg0j35wzcjmx(Actions run):extensions/slack/src/monitor/media.test.ts: 35/35 passed.pnpm check:changed: extension production/test typechecks, lint, guards, and import-cycle checks passed.Risk checklist
Closes: N/A (no existing issue)