mirror of
https://github.com/juanfont/headscale.git
synced 2026-07-08 00:50:20 +09:00
types: reject port-bearing server_url under base_domain
This commit is contained in:
@@ -1301,23 +1301,11 @@ func isSafeServerURL(serverURL, baseDomain string) error {
|
||||
return errServerURLSame
|
||||
}
|
||||
|
||||
serverDomainParts := strings.Split(server.Host, ".")
|
||||
baseDomainParts := strings.Split(baseDomain, ".")
|
||||
|
||||
if len(serverDomainParts) <= len(baseDomainParts) {
|
||||
return nil
|
||||
if strings.HasSuffix(server.Hostname(), "."+baseDomain) {
|
||||
return errServerURLSuffix
|
||||
}
|
||||
|
||||
s := len(serverDomainParts)
|
||||
|
||||
b := len(baseDomainParts)
|
||||
for i := range baseDomainParts {
|
||||
if serverDomainParts[s-i-1] != baseDomainParts[b-i-1] {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return errServerURLSuffix
|
||||
return nil
|
||||
}
|
||||
|
||||
type deprecator struct {
|
||||
|
||||
@@ -507,6 +507,47 @@ func TestSafeServerURL(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSafeServerURLWithPort(t *testing.T) {
|
||||
tests := []struct {
|
||||
serverURL, baseDomain,
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
serverURL: "https://server.headscale.com:443",
|
||||
baseDomain: "headscale.com",
|
||||
wantErr: errServerURLSuffix.Error(),
|
||||
},
|
||||
{
|
||||
serverURL: "https://server.subdomain.headscale.com:8080",
|
||||
baseDomain: "headscale.com",
|
||||
wantErr: errServerURLSuffix.Error(),
|
||||
},
|
||||
{
|
||||
serverURL: "https://headscale.com:443",
|
||||
baseDomain: "headscale.com",
|
||||
wantErr: errServerURLSame.Error(),
|
||||
},
|
||||
{
|
||||
serverURL: "https://example.com:8080",
|
||||
baseDomain: "example.org",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
testName := fmt.Sprintf("server=%s domain=%s", tt.serverURL, tt.baseDomain)
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
err := isSafeServerURL(tt.serverURL, tt.baseDomain)
|
||||
if tt.wantErr != "" {
|
||||
assert.EqualError(t, err, tt.wantErr)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestConfigJSONOmitsSecrets verifies that marshalling a [Config] to JSON
|
||||
// (as /debug/config does via [state.State.DebugConfig]) does not leak the
|
||||
// Postgres password, the OIDC client secret, or the headscale admin
|
||||
|
||||
Reference in New Issue
Block a user