Skip to content

Fix ProxyOriginOf for opaque/scheme-less URLs and userinfo leakage #5176

@yrobla

Description

@yrobla

Context

Identified in PR #5142 review by @JAORMX and Copilot.

Problem

ProxyOriginOf in pkg/llmgateway/config.go has several correctness gaps:

  1. Opaque URLs: url.Parse("localhost:14000/v1") parses as Scheme=localhost, Opaque=14000/v1. The function clears Path but not Opaque, so the path survives in the result — contradicting the doc comment that says "only the scheme and host remain."

  2. ForceQuery: Clearing RawQuery alone may still produce a trailing ? if u.ForceQuery is true (e.g. parsing http://host/path?). u.ForceQuery must also be set to false.

  3. Fragment: Fragment is not cleared — if ProxyBaseURL ever contains one, it leaks into the written settings file.

  4. Userinfo: u.User is not cleared. If ProxyBaseURL ever carries user credentials, they'd be persisted to a user-readable settings file. Should be set to nil.

  5. Validation: There's no guard that u.Host != "" after parsing. For scheme-less inputs the function may return a non-origin result silently.

Suggested fix

func ProxyOriginOf(rawURL string) string {
    u, err := url.Parse(rawURL)
    if err != nil || u.Host == "" {
        return rawURL
    }
    return (&url.URL{Scheme: u.Scheme, Host: u.Host}).String()
}

Explicitly reconstructing from Scheme+Host is simpler and correct by construction — no fields to forget to clear.

Test cases to add (pkg/llmgateway/config_test.go)

  • Empty input
  • Opaque URL (localhost:14000/v1)
  • Scheme-less host:port
  • URL with userinfo
  • IPv6 host
  • Fragment-only (http://host/path#frag)
  • ForceQuery (http://host/path?)
  • Valid full URL (happy path)

References

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinggoPull requests that update go codellm gatewayLLM gateway authentication feature

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions