✨ Add useCardFetch hook for custom card data fetching#4230
✨ Add useCardFetch hook for custom card data fetching#4230clubanderson merged 2 commits intomainfrom
Conversation
Custom Tier 2 cards can now fetch external API data via useCardFetch(),
which routes requests through a backend proxy at /api/card-proxy.
Backend (Go):
- New CardProxyHandler with SSRF protection (private IP blocking)
- URL validation, 5 MB response limit, 15s timeout
- No redirects followed, GET-only
Frontend (TypeScript):
- useCardFetch<T>(url, options) hook injected into sandbox scope
- Returns { data, loading, error, refetch }
- Auto-refresh support with 5s minimum interval
- Max 5 concurrent fetches per card, cleanup on unmount
fetch/XMLHttpRequest remain blocked in the sandbox — useCardFetch is
the only sanctioned way for card code to retrieve external data.
Closes #4205
Signed-off-by: Andrew Anderson <andy@clubanderson.com>
✅ Deploy Preview for kubestellarconsole ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
👋 Hey @clubanderson — thanks for opening this PR!
This is an automated message. |
|
/lgtm |
|
@clubanderson: you cannot LGTM your own PR. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: clubanderson The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
1. Move IP blocking into custom DialContext on cardProxyClient transport, preventing DNS rebinding / TOCTOU bypass (resolve + check at connect time) 2. Refactor useCardFetch to createCardFetchScope() factory — each card gets its own concurrency counter, so unmounting one card doesn't corrupt another 3. Initialize loading=true when URL is provided (fix brief false-idle flash) 4. Fix stale comment: blockedIPPrefixes → blockedCIDRs Signed-off-by: Andrew Anderson <andy@clubanderson.com>
|
Thank you for your contribution! Your PR has been merged. Check out what's new:
Stay connected: Slack #kubestellar-dev | Multi-Cluster Survey |
Follow-up to #4230 addressing code review and silent-failure findings: Backend (card_proxy.go): - CIDR parse failure now log.Fatalf instead of silent skip - Use http.NewRequestWithContext for client disconnect cancellation - Detect 3xx redirects and return helpful error instead of opaque status - Add logging on all error paths + audit log on success - Log response size on oversized body rejection Frontend (useCardFetch.ts): - Add AbortController to cancel in-flight fetches on URL change/unmount - Guard localStorage.getItem against SecurityError in sandboxed iframes - Set loading=false when concurrency limit is hit - Wrap res.json() with helpful error for non-JSON 200 responses Signed-off-by: Andrew Anderson <andy@clubanderson.com>
…#4237) Follow-up to #4230 addressing code review and silent-failure findings: Backend (card_proxy.go): - CIDR parse failure now log.Fatalf instead of silent skip - Use http.NewRequestWithContext for client disconnect cancellation - Detect 3xx redirects and return helpful error instead of opaque status - Add logging on all error paths + audit log on success - Log response size on oversized body rejection Frontend (useCardFetch.ts): - Add AbortController to cancel in-flight fetches on URL change/unmount - Guard localStorage.getItem against SecurityError in sandboxed iframes - Set loading=false when concurrency limit is hit - Wrap res.json() with helpful error for non-JSON 200 responses Signed-off-by: Andrew Anderson <andy@clubanderson.com>
Summary
useCardFetch(url, options)hook to the Tier 2 custom card sandbox, enabling cards to fetch data from external API endpoints/api/card-proxywith SSRF protection (private IP blocking, URL validation, response size limits)fetch/XMLHttpRequestremain blocked in the sandbox —useCardFetchis the only sanctioned way for card code to retrieve external dataUsage in custom card code
Security
Test plan
TestIsBlockedIP)useCardFetchto fetch from a public APIFixes #4205