You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Browser apps frequently need to fetch URLs from origins that don't return CORS headers — git remotes (GitHub/GitLab/Gitea), other Solid pods exposing linked data, ActivityPub actors, Nostr relays' HTTP endpoints, RSS/Atom feeds, images, etc. Public CORS proxies (cors.isomorphic-git.org, etc.) work but introduce third-party trust, privacy, and uptime concerns.
JSS already has the building blocks (`src/utils/ssrf.js`, WAC, optional `--pay`) for a self-hosted, authenticated CORS proxy that any browser-side Solid app can use. This issue tracks the general-purpose feature; the git-specific request in #377 is a special case (proxy a git URL through this).
Phase 1 — WAC-gated, free
Flag
`--cors-proxy`
Endpoint
`/proxy/` (or `/proxy?url=...`)
Auth
WAC on the `/proxy/` resource. Pod owner writes a `.acl` granting whatever scope they want — themselves, a list of WebIDs, `foaf:Agent`, or fully public.
Forwards
request method, body, headers — minus origin-bound ones (`Origin`, `Host`, `Cookie`, `Referer`); preserves `Authorization` and `Git-Protocol` so smart-HTTP and bearer-auth flows work.
Adds to response
`Access-Control-Allow-Origin`, `Access-Control-Allow-Methods`, `Access-Control-Allow-Headers`, `Access-Control-Expose-Headers` (centralized const, same shape as `GIT_CORS_HEADERS` from #374).
SSRF guard
`src/utils/ssrf.js` on initial URL and on every redirect hop (DNS rebinding mitigation). Blocks RFC1918, link-local, loopback, IPv6 equivalents. Blocks unusual ports unless allowlisted.
Limits
Max upstream response size (configurable, default e.g. 50 MB), max upstream timeout, max redirects (default 5).
Streaming
Response is streamed, not buffered, so large pack files / images don't blow memory.
Estimate
~250–400 LOC handler + a handful of tests + flag plumbing in `bin/jss.js`, `src/config.js`, `src/server.js`. 1–2 days for a competent dev.
Phase 2 — optional `--pay` integration (deferred)
Layered on top of Phase 1:
Per-request debit at `--pay-cost`
Optional `--pay-per-byte` for bandwidth pricing
Free-tier rate limit per WebID before paid tier kicks in
402 ↔ 401 mapping so git clients (which don't speak 402) can still surface the gate as a credentials prompt
Anywhere a Solid browser app currently has to either give up or use a third-party proxy
Risks / caveats
SSRF is the dominant risk. This endpoint by definition fetches arbitrary URLs. Existing `src/utils/ssrf.js` covers initial-URL validation; the new work is re-validating every redirect target (otherwise an attacker hosts a 302 to `169.254.169.254`).
Open-relay reputation: an unauthenticated/public proxy will get added to spam blocklists and abuse reports. The WAC gate is the mitigation — pod operators control their own audience.
Resource exhaustion: bandwidth and memory bounds are required. `--cors-proxy-max-bytes`, request timeout, and redirect cap are non-optional.
Header smuggling: be deliberate about the request-header allowlist. `Cookie`, `Authorization`, and `Origin` need explicit policy. Phase 1 default: forward `Authorization` + `Git-Protocol` + `Content-Type` + `Accept*`; strip the rest.
Browser apps frequently need to fetch URLs from origins that don't return CORS headers — git remotes (GitHub/GitLab/Gitea), other Solid pods exposing linked data, ActivityPub actors, Nostr relays' HTTP endpoints, RSS/Atom feeds, images, etc. Public CORS proxies (cors.isomorphic-git.org, etc.) work but introduce third-party trust, privacy, and uptime concerns.
JSS already has the building blocks (`src/utils/ssrf.js`, WAC, optional `--pay`) for a self-hosted, authenticated CORS proxy that any browser-side Solid app can use. This issue tracks the general-purpose feature; the git-specific request in #377 is a special case (proxy a git URL through this).
Phase 1 — WAC-gated, free
Estimate
~250–400 LOC handler + a handful of tests + flag plumbing in `bin/jss.js`, `src/config.js`, `src/server.js`. 1–2 days for a competent dev.
Phase 2 — optional `--pay` integration (deferred)
Layered on top of Phase 1:
Not part of v1; tracked here for context.
Use cases unlocked
Risks / caveats
Refs
git-protocolheader in CORS preflight responses #371, git handler: collapse multi-slash in URL before forwarding to http-backend (#373) #374 — git CORS work that the response-side header logic generalizes from