Skip to content

Commit

Permalink
Block ability to use '*'. replace origins string to a list to config.…
Browse files Browse the repository at this point in the history
… disabled unwanted enpoints for enabling cors
  • Loading branch information
Jisse-Meruma committed Feb 5, 2025
1 parent 68ce697 commit 2918796
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 9 deletions.
13 changes: 8 additions & 5 deletions config-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,15 @@ grpc_listen_addr: 127.0.0.1:50443
# are doing.
grpc_allow_insecure: false

# The Access-Control-Allow-Origin header specifies which origins are allowed to access resources.
# The allow_origins list will allow you to set the Access-Control-Allow-Origin header to the origin in the list.
# This will allow you to enable cors and set headscale without a reverse proxy.
# Multiple origins can be set in the allow_origins list.
# Options:
# - "*" to allow access from any origin (not recommended for sensitive data).
# - "http://example.com" to only allow access from a specific origin.
# - "" to disable Cross-Origin Resource Sharing (CORS).
access_control_allow_origin: ""
# - "*" is disabled (due to security risks).
# - "https://example.com" to only allow access from a specific origin.
# - "https://example.com:1234" to allow access from a specific origin with a port.
cors:
allow_origins: []

# The Noise section includes specific configuration for the
# TS2021 Noise protocol
Expand Down
38 changes: 36 additions & 2 deletions hscontrol/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,18 +455,52 @@ func (h *Headscale) ensureUnixSocketIsAbsent() error {
return os.Remove(h.cfg.UnixSocket)
}

// corsHeaderMiddleware will add an "Access-Control-Allow-Origin" to enable CORS
func (h *Headscale) corsHeadersMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", h.cfg.AccessControlAllowOrigins)

// skip disabled CORS endpoints
if h.shouldSkipCORSCheck(r.URL.Path) {
next.ServeHTTP(w, r)
return
}

origin := r.Header.Get("Origin")
// we compare origin from the allowed Origins list. Then add the header with origin
for _, allowedOrigin := range h.cfg.AllowedOrigins.Origins {
if allowedOrigin == origin {
w.Header().Set("Vary", "Origin")
w.Header().Set("Access-Control-Allow-Origin", allowedOrigin)
break
}
}
next.ServeHTTP(w, r)
})
}

func (h *Headscale) shouldSkipCORSCheck(routerPath string) bool {
// A list of disabled CORS endpoints
var routesToSkipCors = []string{
"/swagger",
"/swagger/v1/openapiv2.json",
"/apple",
"/apple/{platform}",
"/windows",
}

for _, routes := range routesToSkipCors {
if routes == routerPath {
return true
}
}
return false
}

func (h *Headscale) createRouter(grpcMux *grpcRuntime.ServeMux) *mux.Router {
router := mux.NewRouter()
router.Use(prometheusMiddleware)

if h.cfg.AccessControlAllowOrigins != "" {
if len(h.cfg.AllowedOrigins.Origins) != 0 {
router.Use(h.corsHeadersMiddleware)
}

Expand Down
16 changes: 14 additions & 2 deletions hscontrol/types/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ type Config struct {
Log LogConfig
DisableUpdateCheck bool

AccessControlAllowOrigins string
AllowedOrigins CorsConfig

Database DatabaseConfig

Expand Down Expand Up @@ -210,6 +210,10 @@ type LogTailConfig struct {
Enabled bool
}

type CorsConfig struct {
Origins []string;
}

type CLIConfig struct {
Address string
APIKey string
Expand Down Expand Up @@ -534,6 +538,14 @@ func logtailConfig() LogTailConfig {
}
}

func corsConfig() CorsConfig {
allowedOrigins := viper.GetStringSlice("cors.allowed_origins")

return CorsConfig{
Origins: allowedOrigins,
}
}

func policyConfig() PolicyConfig {
policyPath := viper.GetString("policy.path")
policyMode := viper.GetString("policy.mode")
Expand Down Expand Up @@ -907,7 +919,7 @@ func LoadServerConfig() (*Config, error) {
GRPCAllowInsecure: viper.GetBool("grpc_allow_insecure"),
DisableUpdateCheck: false,

AccessControlAllowOrigins: viper.GetString("access_control_allow_origin"),
AllowedOrigins: corsConfig(),

PrefixV4: prefix4,
PrefixV6: prefix6,
Expand Down

0 comments on commit 2918796

Please sign in to comment.