Skip to content

[history server] Add redirect capability to enter_cluster - #5086

Open
KunWuLuan wants to merge 2 commits into
ray-project:masterfrom
KunWuLuan:feat/historyserver-enter-cluster-redirect
Open

[history server] Add redirect capability to enter_cluster#5086
KunWuLuan wants to merge 2 commits into
ray-project:masterfrom
KunWuLuan:feat/historyserver-enter-cluster-redirect

Conversation

@KunWuLuan

Copy link
Copy Markdown
Contributor

Why

Entering a cluster today requires two steps: hit the enter_cluster endpoint to establish the cluster context (via Set-Cookie), then separately navigate to the dashboard. This makes it awkward to hand out a single link that both sets context and lands the user on a useful page.

What

Adds an optional redirect query parameter to the enter_cluster endpoint (both the .../{name} and .../{name}/{session} routes).

  • When redirect is set, the handler responds with a 302 to the given path instead of the JSON body. The Set-Cookie headers still ride along on the redirect response, so a single navigation both establishes the cluster context and lands on the target page.

  • Example:
    /enter_cluster////latest?redirect=/#/overview

  • When redirect is not set, behavior is unchanged — the endpoint still returns the existing JSON response.

Security

Redirect targets are validated by a new isSafeRedirectPath helper to prevent open-redirect attacks. Only same-origin, site-local absolute paths are allowed:

  • Must start with a single /
  • Rejects protocol-relative (//host) and backslash (/\host) variants
  • Rejects anything carrying a URL scheme or host component (http://…, javascript:…)

Unsafe targets are logged and rejected with a 400.

Testing

  • TestIsSafeRedirectPath — table-driven coverage of safe paths and rejected attack vectors (protocol-relative, backslash, absolute URL, scheme-only, empty, relative).
  • TestEnterClusterRedirect — end-to-end route behavior:
    • valid redirect returns 302 with the correct Location and cookies preserved
    • unsafe redirect returns 400
    • no redirect param still returns the 200 JSON response

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit d5089e4. Configure here.

Comment thread historyserver/pkg/historyserver/router.go
Comment thread historyserver/pkg/historyserver/router.go
test added 2 commits August 11, 2026 10:52
Add an optional `redirect` query parameter to the enter_cluster endpoint.
When set, the handler responds with a 302 to the given path (Set-Cookie
headers still ride along on the redirect) instead of the JSON body, so a
single navigation both establishes the cluster context and lands on the
dashboard, e.g. /enter_cluster/<ns>/<kind>/<name>/latest?redirect=/#/overview

Redirect targets are validated by isSafeRedirectPath to prevent open
redirects: only same-origin absolute paths are allowed. Behavior without
the parameter is unchanged (still returns JSON).
@KunWuLuan
KunWuLuan force-pushed the feat/historyserver-enter-cluster-redirect branch from d5089e4 to 5e454cf Compare August 11, 2026 03:00
@machichima

Copy link
Copy Markdown
Collaborator

I tried this PR, following docs here to start ray dashboard and proxy to history server

https://docs.ray.io/en/master/cluster/kubernetes/user-guides/kuberay-history-server.html#start-the-local-ray-dashboard

However, when trying with: http://localhost:8265/enter_cluster/default/raycluster/raycluster-historyserver?redirect=/#/overview

I'll get 404: Not Found

Comment on lines +323 to +325
if strings.HasPrefix(target, "//") || strings.HasPrefix(target, "/\\") {
return false
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may get something like redirect=/x/../\evil.com, which have \ in the middle. Could we use strings.Contains(target, "\\") here?

// instead of JSON. The Set-Cookie headers above still ride along on the
// redirect response, so a single navigation both establishes the cluster
// context and lands on the dashboard (e.g. /enter_cluster/...?redirect=/#/overview).
if redirect := r1.QueryParameter("redirect"); redirect != "" {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move this check above the Set-Cookie calls, so cookies aren't updated when the redirect target is invalid?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants