From 627c79dea1d4f9ef884d09a6e9e0a0876bcb9036 Mon Sep 17 00:00:00 2001 From: Willy Kloucek Date: Mon, 4 Jul 2022 11:35:35 +0200 Subject: [PATCH] mask sensitive values in /config proxy debug server endpoint --- .../fix-sensitive-values-proxy-debug-config.md | 6 ++++++ go.mod | 1 + go.sum | 2 ++ ocis-pkg/shared/shared_types.go | 10 +++++----- services/proxy/pkg/config/config.go | 12 ++++++------ services/proxy/pkg/config/debug.go | 2 +- services/proxy/pkg/server/debug/server.go | 8 +++++++- 7 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 changelog/unreleased/fix-sensitive-values-proxy-debug-config.md diff --git a/changelog/unreleased/fix-sensitive-values-proxy-debug-config.md b/changelog/unreleased/fix-sensitive-values-proxy-debug-config.md new file mode 100644 index 00000000000..cc56150a07a --- /dev/null +++ b/changelog/unreleased/fix-sensitive-values-proxy-debug-config.md @@ -0,0 +1,6 @@ +Bugfix: Fix make sensitive config values in the proxy's debug server + +We've fixed a security issue of the proxy's debug server config report endpoint. +Previously sensitive configuration values haven't been masked. We now mask these values. + +https://github.com/owncloud/ocis/pull/4086 diff --git a/go.mod b/go.mod index c8969c88907..129bf44b56f 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/cs3org/go-cs3apis v0.0.0-20220512100524-551800f020d8 github.com/cs3org/reva/v2 v2.6.1 github.com/disintegration/imaging v1.6.2 + github.com/ggwhite/go-masker v1.0.9 github.com/go-chi/chi/v5 v5.0.7 github.com/go-chi/cors v1.2.1 github.com/go-chi/render v1.0.1 diff --git a/go.sum b/go.sum index 15c0c6a068a..e84dcd7997b 100644 --- a/go.sum +++ b/go.sum @@ -368,6 +368,8 @@ github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmx github.com/gdexlab/go-render v1.0.1 h1:rxqB3vo5s4n1kF0ySmoNeSPRYkEsyHgln4jFIQY7v0U= github.com/gdexlab/go-render v1.0.1/go.mod h1:wRi5nW2qfjiGj4mPukH4UV0IknS1cHD4VgFTmJX5JzM= github.com/getkin/kin-openapi v0.13.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw= +github.com/ggwhite/go-masker v1.0.9 h1:9mKJzhLwJN1E5ekqNMk2ppP9ntWubIGtrUNV9wRouZo= +github.com/ggwhite/go-masker v1.0.9/go.mod h1:xnTRHwrIU9FtBADwEjUC5Dy/BVedvoTxyOE7/d3CNwY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= diff --git a/ocis-pkg/shared/shared_types.go b/ocis-pkg/shared/shared_types.go index 11cfdab1913..e171f6fe76f 100644 --- a/ocis-pkg/shared/shared_types.go +++ b/ocis-pkg/shared/shared_types.go @@ -26,7 +26,7 @@ type Tracing struct { // TokenManager is the config for using the reva token manager type TokenManager struct { - JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET" desc:"The secret to mint and validate jwt tokens."` + JWTSecret string `mask:"password" yaml:"jwt_secret" env:"OCIS_JWT_SECRET" desc:"The secret to mint and validate jwt tokens."` } // Reva defines all available REVA configuration. @@ -40,11 +40,11 @@ type Commons struct { Log *Log `yaml:"log"` Tracing *Tracing `yaml:"tracing"` OcisURL string `yaml:"ocis_url" env:"OCIS_URL" desc:"URL, where oCIS is reachable for users."` - TokenManager *TokenManager `yaml:"token_manager"` + TokenManager *TokenManager `mask:"struct" yaml:"token_manager"` Reva *Reva `yaml:"reva"` - MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used for accessing the 'auth-machine' service to impersonate users."` - TransferSecret string `yaml:"transfer_secret,omitempty" env:"REVA_TRANSFER_SECRET"` + MachineAuthAPIKey string `mask:"password" yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used for accessing the 'auth-machine' service to impersonate users."` + TransferSecret string `mask:"password" yaml:"transfer_secret,omitempty" env:"REVA_TRANSFER_SECRET"` SystemUserID string `yaml:"system_user_id" env:"OCIS_SYSTEM_USER_ID" desc:"ID of the oCIS storage-system system user. Admins need to set the ID for the storage-system system user in this config option which is then used to reference the user. Any reasonable long string is possible, preferably this would be an UUIDv4 format."` - SystemUserAPIKey string `yaml:"system_user_api_key" env:"SYSTEM_USER_API_KEY"` + SystemUserAPIKey string `mask:"password" yaml:"system_user_api_key" env:"SYSTEM_USER_API_KEY"` AdminUserID string `yaml:"admin_user_id" env:"OCIS_ADMIN_USER_ID" desc:"ID of a user, that should receive admin privileges."` } diff --git a/services/proxy/pkg/config/config.go b/services/proxy/pkg/config/config.go index c68f9597577..bab27484460 100644 --- a/services/proxy/pkg/config/config.go +++ b/services/proxy/pkg/config/config.go @@ -8,13 +8,13 @@ import ( // Config combines all available configuration parts. type Config struct { - Commons *shared.Commons `yaml:"-"` // don't use this directly as configuration for a service + Commons *shared.Commons `mask:"struct" yaml:"-"` // don't use this directly as configuration for a service Service Service `yaml:"-"` Tracing *Tracing `yaml:"tracing"` Log *Log `yaml:"log"` - Debug Debug `yaml:"debug"` + Debug Debug `mask:"struct" yaml:"debug"` HTTP HTTP `yaml:"http"` @@ -22,19 +22,19 @@ type Config struct { Policies []Policy `yaml:"policies"` OIDC OIDC `yaml:"oidc"` - TokenManager *TokenManager `yaml:"token_manager"` + TokenManager *TokenManager `mask:"struct" yaml:"token_manager"` PolicySelector *PolicySelector `yaml:"policy_selector"` PreSignedURL PreSignedURL `yaml:"pre_signed_url"` AccountBackend string `yaml:"account_backend" env:"PROXY_ACCOUNT_BACKEND_TYPE" desc:"Account backend the proxy should use, currenly only 'cs3' is possible here."` UserOIDCClaim string `yaml:"user_oidc_claim" env:"PROXY_USER_OIDC_CLAIM" desc:"The name of an OpenID Connect claim that should be used for resolving users with the account backend. Currently defaults to 'email'."` UserCS3Claim string `yaml:"user_cs3_claim" env:"PROXY_USER_CS3_CLAIM" desc:"The name of a CS3 user attribute (claim) that should be mapped to the 'user_oidc_claim'. Currently defaults to 'mail' (other possible values are: 'username', 'displayname')"` - MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;PROXY_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used for accessing the 'auth-machine' service to impersonate users."` + MachineAuthAPIKey string `mask:"password" yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;PROXY_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used for accessing the 'auth-machine' service to impersonate users."` AutoprovisionAccounts bool `yaml:"auto_provision_accounts" env:"PROXY_AUTOPROVISION_ACCOUNTS" desc:"Set this to 'true' to automatically provsion users that do not yet exist in the users service on-demand upon first signin. To use this a write-enabled libregraph user backend needs to be setup an running."` EnableBasicAuth bool `yaml:"enable_basic_auth" env:"PROXY_ENABLE_BASIC_AUTH" desc:"Set this to true to enable 'basic' (username/password) authentication."` InsecureBackends bool `yaml:"insecure_backends" env:"PROXY_INSECURE_BACKENDS" desc:"Disable TLS certificate validation for all http backend connections."` AuthMiddleware AuthMiddleware `yaml:"auth_middleware"` - Context context.Context `yaml:"-"` + Context context.Context `yaml:"-" json:"-"` } // Policy enables us to use multiple directors. @@ -108,7 +108,7 @@ type StaticSelectorConf struct { // TokenManager is the config for using the reva token manager type TokenManager struct { - JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;PROXY_JWT_SECRET" desc:"The secret to mint and validate jwt tokens."` + JWTSecret string `mask:"password" yaml:"jwt_secret" env:"OCIS_JWT_SECRET;PROXY_JWT_SECRET" desc:"The secret to mint and validate jwt tokens."` } // PreSignedURL is the config for the presigned url middleware diff --git a/services/proxy/pkg/config/debug.go b/services/proxy/pkg/config/debug.go index f4133e97e7d..3a3c491266b 100644 --- a/services/proxy/pkg/config/debug.go +++ b/services/proxy/pkg/config/debug.go @@ -3,7 +3,7 @@ package config // Debug defines the available debug configuration. type Debug struct { Addr string `yaml:"addr" env:"PROXY_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."` - Token string `yaml:"token" env:"PROXY_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"` + Token string `mask:"password" yaml:"token" env:"PROXY_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint"` Pprof bool `yaml:"pprof" env:"PROXY_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling"` Zpages bool `yaml:"zpages" env:"PROXY_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."` } diff --git a/services/proxy/pkg/server/debug/server.go b/services/proxy/pkg/server/debug/server.go index ccc766ab32c..a3e599cbd24 100644 --- a/services/proxy/pkg/server/debug/server.go +++ b/services/proxy/pkg/server/debug/server.go @@ -5,6 +5,7 @@ import ( "io" "net/http" + masker "github.com/ggwhite/go-masker" "github.com/owncloud/ocis/v2/ocis-pkg/service/debug" "github.com/owncloud/ocis/v2/ocis-pkg/version" "github.com/owncloud/ocis/v2/services/proxy/pkg/config" @@ -65,7 +66,12 @@ func configDump(cfg *config.Config) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - b, err := json.Marshal(cfg) + maskedCfg, err := masker.Struct(cfg) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + } + + b, err := json.Marshal(maskedCfg) if err != nil { w.WriteHeader(http.StatusInternalServerError) }