Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,3 +361,7 @@ Remember: You're Sentinel, the guardian of switchAILocal. Security is not option
**Vulnerability:** The CLI executor proxy lacked scheme validation for the user-controlled `remoteHost`, creating an SSRF vulnerability. The OAuth callback forwarder lacked prefix validation for `targetBase`, creating an open redirect vulnerability.
**Learning:** Taint analysis revealed that input passed from management configurations or remote host specifications must be strictly validated before being used in HTTP requests or redirect targets to prevent protocol abuse and unauthorized redirects.
**Prevention:** Always enforce strict protocol validation (e.g., scheme is 'http' or 'https') for outbound requests and validate redirect targets against allowed prefixes (e.g., 'http://localhost' or '/').
## 2026-08-12 - Prevent SSRF with explicit URL scheme and host validation
**Vulnerability:** Taint analysis flagged an SSRF (Server-Side Request Forgery) vulnerability in the remote execution flow where the host URL was built insecurely, allowing arbitrary host modification or bypass of validation.
**Learning:** Basic string operations or prefix checks are insufficient to mitigate SSRF when dealing with unvalidated remote hosts in execution flow. Using `net/url` to explicitly parse and validate components is required.
**Prevention:** Avoid string concatenation for URLs involving external input. Always use `net/url`'s `url.Parse` to parse the URL, explicitly validate the `Host` and `Scheme` properties, and safely reconstruct the target URL using a `url.URL{...}` struct literal.
12 changes: 7 additions & 5 deletions internal/runtime/executor/cli_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,13 @@ func (e *LocalCLIExecutor) executeRemote(ctx context.Context, remoteHost, binary
return switchailocalexecutor.Response{}, fmt.Errorf("invalid remote host URL, must use http or https scheme and include a host")
}

targetURL := *parsedURL
targetURL.Path = strings.TrimSuffix(targetURL.Path, "/") + "/run"
targetURL.RawPath = ""
targetURL.Fragment = ""
targetURL.RawFragment = ""
targetURL := url.URL{
Scheme: parsedURL.Scheme,
User: parsedURL.User,
Host: parsedURL.Host,
Path: strings.TrimSuffix(parsedURL.Path, "/") + "/run",
RawQuery: parsedURL.RawQuery,
}

httpReq, err := http.NewRequestWithContext(ctx, "POST", targetURL.String(), bytes.NewReader(jsonBody))
if err != nil {
Expand Down
Loading