fix(xcecli): assert own hostname as FROM_HOST at submission time (bug-1676, gitea #44)

JobSubmitRequest gains a FromHost field, populated in BuildJobRequest()
via os.Hostname(). Matches how traditional batch schedulers report the
submitting host, and sidesteps having the server derive it from the
connection (which apiserver was doing via ctx.ClientIP() -- an IP not
a hostname, and spoofable via X-Forwarded-For since this apiserver
never configures gin's TrustedProxies).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AgYRU3zDTqNGV5Jk8aiKLg
This commit is contained in:
Rongsong Shen 2026-08-24 15:14:28 +00:00
parent 590e2a726e
commit 4fad788430
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
3 changed files with 37 additions and 0 deletions

View file

@ -400,6 +400,15 @@ func (js *JobSubmitter) BuildJobRequest() (*models.JobSubmitRequest, error) {
jobReq.CWD = cwd
}
// bug-1676: assert our own hostname as the submitting host rather than
// relying on the server deriving it from the connection (spoofable via
// X-Forwarded-For, and only ever an IP, never a hostname) -- matches how
// traditional batch schedulers report FROM_HOST. Best-effort: an error
// here just leaves FromHost empty, same as omitting the field entirely.
if hostname, err := os.Hostname(); err == nil {
jobReq.FromHost = hostname
}
if js.askedHosts != "" {
jobReq.AskedHosts = js.askedHosts
}

View file

@ -0,0 +1,27 @@
package jobs
import (
"os"
"testing"
)
// bug-1676: BuildJobRequest asserts our own hostname as FromHost rather than
// leaving it for the server to derive from the connection (spoofable via
// X-Forwarded-For, and only ever an IP, never a hostname).
func TestBuildJobRequest_SetsFromHostToLocalHostname(t *testing.T) {
js := NewJobSubmitter(nil)
js.command = "sleep 1"
req, err := js.BuildJobRequest()
if err != nil {
t.Fatalf("BuildJobRequest: %v", err)
}
wantHost, hostErr := os.Hostname()
if hostErr != nil {
t.Skipf("os.Hostname() unavailable in this environment: %v", hostErr)
}
if req.FromHost != wantHost {
t.Errorf("FromHost = %q, want local hostname %q", req.FromHost, wantHost)
}
}

View file

@ -338,6 +338,7 @@ type JobSubmitRequest struct {
ChkpntDir string `json:"chkpnt_dir,omitempty"`
InitChkpntPeriod int `json:"init_chkpnt_period,omitempty"`
CWD string `json:"cwd,omitempty"`
FromHost string `json:"from_host,omitempty"` // bug-1676: submitting host's own hostname, set by BuildJobRequest via os.Hostname()
OutDir string `json:"out_dir,omitempty"`
InFile string `json:"in_file,omitempty"`
OutFile string `json:"out_file,omitempty"`