From e9da3a871d8ae9da6d9dc4217ec80547d0f39825 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 11 Feb 2021 20:10:48 -0500 Subject: [PATCH] Switch on CORS by default if not specified (#928) --- CHANGELOG.md | 5 ++++ go.mod | 2 +- go.sum | 2 ++ internal/cmd/base/servers.go | 16 +++++++++++-- internal/cmd/commands/dev/dev.go | 32 +++++++++++++++----------- internal/cmd/commands/server/server.go | 11 +++++---- internal/cmd/config/config.go | 11 +++++++++ internal/cmd/config/config_test.go | 4 +++- internal/servers/controller/handler.go | 2 +- 9 files changed, 62 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69a6009cf..6ebddb6bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,11 @@ Canonical reference for changes, improvements, and bugfixes for Boundary. * `type=;actions=` where one of the actions is _not_ `create` or `list`. This format operates only on collections so assigning more actions this way will never work +* CORS: CORS is now turned on by default when running with `boundary server` + with an `allowed_origins` value of `*`. You can disable it with `cors_enabled + = false` or if you want to change parameters, set `cors_enabled = true` and + the other related configuration values. It was always turned on when running + `boundary dev` and this provides a more consistent experience. ### New and Improved diff --git a/go.mod b/go.mod index 856695d82..c37fc3c1f 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,7 @@ require ( github.com/hashicorp/go-retryablehttp v0.6.8 github.com/hashicorp/go-uuid v1.0.2 github.com/hashicorp/hcl v1.0.0 - github.com/hashicorp/shared-secure-libs v0.0.2 + github.com/hashicorp/shared-secure-libs v0.0.3 github.com/hashicorp/vault/sdk v0.1.14-0.20200916184745-5576096032f8 github.com/iancoleman/strcase v0.1.3 github.com/jackc/pgx/v4 v4.10.0 diff --git a/go.sum b/go.sum index c8d577152..ee5644479 100644 --- a/go.sum +++ b/go.sum @@ -609,6 +609,8 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/shared-secure-libs v0.0.2 h1:+izKlB8vxpBK+K6zNmB4DZtDEl1a7fB8JmqdBNhnhjs= github.com/hashicorp/shared-secure-libs v0.0.2/go.mod h1:xhtA0FH6AYYFOy0sir7u0O0zzdLi7ofU6oWxy+gjnuc= +github.com/hashicorp/shared-secure-libs v0.0.3 h1:R1ublyNsxQ1EKHdiKlglZ8uhkzPvBcWstFJ85s1me3A= +github.com/hashicorp/shared-secure-libs v0.0.3/go.mod h1:xhtA0FH6AYYFOy0sir7u0O0zzdLi7ofU6oWxy+gjnuc= github.com/hashicorp/vault/api v1.0.5-0.20200514164214-89b1987e38c2/go.mod h1:P8A7gn1a6j/7qQ4zOaWI6FC/Q9jQWEBRTOwZH33tC9o= github.com/hashicorp/vault/api v1.0.5-0.20200519221902-385fac77e20f/go.mod h1:euTFbi2YJgwcju3imEt919lhJKF68nN1cQPq3aA+kBE= github.com/hashicorp/vault/api v1.0.5-0.20200805123347-1ef507638af6 h1:ChHpobQse3kjVX7GmbpUFVqaMTf4lb1gcLrJltsUmS4= diff --git a/internal/cmd/base/servers.go b/internal/cmd/base/servers.go index 8da50e5bf..2ef292e1b 100644 --- a/internal/cmd/base/servers.go +++ b/internal/cmd/base/servers.go @@ -269,8 +269,9 @@ func (b *Server) SetupListeners(ui cli.Ui, config *configutil.SharedConfig, allo defer b.ReloadFuncsLock.Unlock() for i, lnConfig := range config.Listeners { - for _, purpose := range lnConfig.Purpose { - purpose = strings.ToLower(purpose) + var purpose string + for _, p := range lnConfig.Purpose { + purpose = strings.ToLower(p) if !strutil.StrListContains(allowedPurposes, purpose) { return fmt.Errorf("Unknown listener purpose %q", purpose) } @@ -294,6 +295,17 @@ func (b *Server) SetupListeners(ui cli.Ui, config *configutil.SharedConfig, allo return fmt.Errorf("Error initializing listener of type %s: %w", lnConfig.Type, err) } + // CORS props + if purpose == "api" { + if lnConfig.CorsEnabled != nil && *lnConfig.CorsEnabled { + props["cors_enabled"] = "true" + props["cors_allowed_origins"] = fmt.Sprintf("%v", lnConfig.CorsAllowedOrigins) + props["cors_allowed_headers"] = fmt.Sprintf("%v", lnConfig.CorsAllowedHeaders) + } else { + props["cors_enabled"] = "false" + } + } + // X-Forwarded-For props { if len(lnConfig.XForwardedForAuthorizedAddrs) > 0 { diff --git a/internal/cmd/commands/dev/dev.go b/internal/cmd/commands/dev/dev.go index 19a7c6911..fb71592f7 100644 --- a/internal/cmd/commands/dev/dev.go +++ b/internal/cmd/commands/dev/dev.go @@ -323,20 +323,6 @@ func (c *Command) Run(args []string) int { c.Config.PassthroughDirectory = c.flagPassthroughDirectory - if err := c.SetupControllerPublicClusterAddress(c.Config, c.flagControllerPublicClusterAddr); err != nil { - c.UI.Error(err.Error()) - return 1 - } - c.InfoKeys = append(c.InfoKeys, "controller public cluster addr") - c.Info["controller public cluster addr"] = c.Config.Controller.PublicClusterAddr - - if err := c.SetupWorkerPublicAddress(c.Config, c.flagWorkerPublicAddr); err != nil { - c.UI.Error(err.Error()) - return 1 - } - c.InfoKeys = append(c.InfoKeys, "worker public addr") - c.Info["worker public addr"] = c.Config.Worker.PublicAddr - for _, l := range c.Config.Listeners { if len(l.Purpose) != 1 { c.UI.Error("Only one purpose supported for each listener") @@ -355,6 +341,8 @@ func (c *Command) Run(args []string) int { if c.flagControllerClusterListenAddr != "" { l.Address = c.flagControllerClusterListenAddr c.Config.Worker.Controllers = []string{l.Address} + } else { + l.Address = "127.0.0.1:9201" } if strings.HasPrefix(l.Address, "/") { l.Type = "unix" @@ -363,10 +351,26 @@ func (c *Command) Run(args []string) int { case "proxy": if c.flagWorkerProxyListenAddr != "" { l.Address = c.flagWorkerProxyListenAddr + } else { + l.Address = "127.0.0.1:9202" } } } + if err := c.SetupControllerPublicClusterAddress(c.Config, c.flagControllerPublicClusterAddr); err != nil { + c.UI.Error(err.Error()) + return 1 + } + c.InfoKeys = append(c.InfoKeys, "controller public cluster addr") + c.Info["controller public cluster addr"] = c.Config.Controller.PublicClusterAddr + + if err := c.SetupWorkerPublicAddress(c.Config, c.flagWorkerPublicAddr); err != nil { + c.UI.Error(err.Error()) + return 1 + } + c.InfoKeys = append(c.InfoKeys, "worker public proxy addr") + c.Info["worker public proxy addr"] = c.Config.Worker.PublicAddr + if err := c.SetupLogging(c.flagLogLevel, c.flagLogFormat, "", ""); err != nil { c.UI.Error(err.Error()) return 1 diff --git a/internal/cmd/commands/server/server.go b/internal/cmd/commands/server/server.go index 6c95285d0..ab5810887 100644 --- a/internal/cmd/commands/server/server.go +++ b/internal/cmd/commands/server/server.go @@ -204,6 +204,9 @@ func (c *Command) Run(args []string) int { foundApi = true case "proxy": foundProxy = true + if lnConfig.Address == "" { + lnConfig.Address = "127.0.0.1:9202" + } default: c.UI.Error(fmt.Sprintf("Unknown listener purpose %q", lnConfig.Purpose[0])) return 1 @@ -227,8 +230,8 @@ func (c *Command) Run(args []string) int { c.UI.Error(err.Error()) return 1 } - c.InfoKeys = append(c.InfoKeys, "public cluster addr") - c.Info["public cluster addr"] = c.Config.Controller.PublicClusterAddr + c.InfoKeys = append(c.InfoKeys, "controller public cluster addr") + c.Info["controller public cluster addr"] = c.Config.Controller.PublicClusterAddr } if c.Config.Worker != nil { @@ -242,8 +245,8 @@ func (c *Command) Run(args []string) int { c.UI.Error(err.Error()) return 1 } - c.InfoKeys = append(c.InfoKeys, "public proxy addr") - c.Info["public proxy addr"] = c.Config.Worker.PublicAddr + c.InfoKeys = append(c.InfoKeys, "worker public proxy addr") + c.Info["worker public proxy addr"] = c.Config.Worker.PublicAddr } if c.Config.Controller != nil { diff --git a/internal/cmd/config/config.go b/internal/cmd/config/config.go index cd8c6ba56..4cf7ecc64 100644 --- a/internal/cmd/config/config.go +++ b/internal/cmd/config/config.go @@ -327,6 +327,17 @@ func Parse(d string) (*Config, error) { } result.SharedConfig = sharedConfig + // If cors wasn't specified, enable default values + for _, listener := range result.SharedConfig.Listeners { + if strutil.StrListContains(listener.Purpose, "api") { + if listener.CorsEnabled == nil { + listener.CorsEnabled = new(bool) + *listener.CorsEnabled = true + listener.CorsAllowedOrigins = []string{"*"} + } + } + } + return result, nil } diff --git a/internal/cmd/config/config_test.go b/internal/cmd/config/config_test.go index 7092cc7cc..9a9c92b4f 100644 --- a/internal/cmd/config/config_test.go +++ b/internal/cmd/config/config_test.go @@ -14,6 +14,8 @@ func TestDevController(t *testing.T) { t.Fatal(err) } + truePointer := new(bool) + *truePointer = true exp := &Config{ SharedConfig: &configutil.SharedConfig{ DisableMlock: true, @@ -22,7 +24,7 @@ func TestDevController(t *testing.T) { Type: "tcp", Purpose: []string{"api"}, TLSDisable: true, - CorsEnabled: true, + CorsEnabled: truePointer, CorsAllowedOrigins: []string{"*"}, }, { diff --git a/internal/servers/controller/handler.go b/internal/servers/controller/handler.go index 8cae2d68b..ce75256f6 100644 --- a/internal/servers/controller/handler.go +++ b/internal/servers/controller/handler.go @@ -260,7 +260,7 @@ func wrapHandlerWithCors(h http.Handler, props HandlerProperties) http.Handler { }, props.ListenerConfig.CorsAllowedHeaders...) return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - if !props.ListenerConfig.CorsEnabled { + if props.ListenerConfig.CorsEnabled == nil || !*props.ListenerConfig.CorsEnabled { h.ServeHTTP(w, req) return }