Skip to content

Commit

Permalink
feat: add CSP and other security related headers in the oCIS proxy se…
Browse files Browse the repository at this point in the history
…rvice
  • Loading branch information
DeepDiver1975 committed Apr 23, 2024
1 parent a4cc165 commit 9ae23ee
Show file tree
Hide file tree
Showing 20 changed files with 1,489 additions and 1 deletion.
5 changes: 5 additions & 0 deletions changelog/unreleased/csp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Enhancement: Add CSP and other security related headers to oCIS

General hardening of oCIS

https://github.com/owncloud/ocis/pull/8777
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ require (
github.com/thejerf/suture/v4 v4.0.5
github.com/tidwall/gjson v1.17.1
github.com/tus/tusd v1.13.0
github.com/unrolled/secure v1.14.0
github.com/urfave/cli/v2 v2.27.1
github.com/xhit/go-simple-mail/v2 v2.16.0
go-micro.dev/v4 v4.10.2
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2042,6 +2042,8 @@ github.com/tus/tusd v1.13.0 h1:W7rtb1XPSpde/GPZAgdfUS3vus2Jt2KmckS6OUd3CU8=
github.com/tus/tusd v1.13.0/go.mod h1:1tX4CDGlx8koHGFJdSaJ5ybUIm2NeVloJgZEPSKRcQA=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
github.com/unrolled/secure v1.14.0 h1:u9vJTU/pR4Bny0ntLUMxdfLtmIRGvQf2sEFuA0TG9AE=
github.com/unrolled/secure v1.14.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
Expand Down
6 changes: 6 additions & 0 deletions services/proxy/pkg/command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,11 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config,
Now: time.Now,
})

cspConfig, err := middleware.LoadCSPConfig(cfg)
if err != nil {
logger.Fatal().Err(err).Msg("Failed load CSP configuration.")
}

return alice.New(
// first make sure we log all requests and redirect to https if necessary
otelhttp.NewMiddleware("proxy",
Expand All @@ -313,6 +318,7 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config,
chimiddleware.RequestID,
middleware.AccessLog(logger),
middleware.HTTPSRedirect,
middleware.Security(cspConfig),
router.Middleware(cfg.PolicySelector, cfg.Policies, logger),
middleware.Authentication(
authenticators,
Expand Down
3 changes: 2 additions & 1 deletion services/proxy/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type Config struct {
BackendHTTPSCACert string `yaml:"backend_https_cacert" env:"PROXY_HTTPS_CACERT" desc:"Path/File for the root CA certificate used to validate the server’s TLS certificate for https enabled backend services." introductionVersion:"pre5.0"`
AuthMiddleware AuthMiddleware `yaml:"auth_middleware"`
PoliciesMiddleware PoliciesMiddleware `yaml:"policies_middleware"`
CSPConfigFileLocation string `yaml:"csp_config_file_location" env:"PROXY_CSP_CONFIG_FILE_LOCATION" desc:"The location of the CSP configuration file." introductionVersion:"6.0"`

Context context.Context `yaml:"-" json:"-"`
}
Expand Down Expand Up @@ -140,7 +141,7 @@ type RoleAssignment struct {
OIDCRoleMapper OIDCRoleMapper `yaml:"oidc_role_mapper"`
}

// OIDCRoleMapper contains the configuration for the "oidc" role assignment driber
// OIDCRoleMapper contains the configuration for the "oidc" role assignment driver
type OIDCRoleMapper struct {
RoleClaim string `yaml:"role_claim" env:"PROXY_ROLE_ASSIGNMENT_OIDC_CLAIM" desc:"The OIDC claim used to create the users role assignment." introductionVersion:"pre5.0"`
RolesMap []RoleMapping `yaml:"role_mapping" desc:"A list of mappings of ocis role names to PROXY_ROLE_ASSIGNMENT_OIDC_CLAIM claim values. This setting can only be configured in the configuration file and not via environment variables."`
Expand Down
13 changes: 13 additions & 0 deletions services/proxy/pkg/config/csp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package config

import (
_ "embed"
)

// CSP defines CSP header directives
type CSP struct {
Directives map[string][]string `yaml:"directives"`
}

//go:embed csp.yaml
var DefaultCSPConfig string
29 changes: 29 additions & 0 deletions services/proxy/pkg/config/csp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
directives:
child-src:
- '''self'''
connect-src:
- '''self'''
default-src:
- '''none'''
font-src:
- '''self'''
frame-src:
- '''self'''
- 'https://embed.diagrams.net/'
img-src:
- '''self'''
- 'data:'
- 'blob:'
manifest-src:
- '''self'''
media-src:
- '''self'''
object-src:
- '''self'''
- 'blob:'
script-src:
- '''self'''
- '''unsafe-inline'''
style-src:
- '''self'''
- '''unsafe-inline'''
1 change: 1 addition & 0 deletions services/proxy/pkg/config/defaults/defaultconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func DefaultConfig() *config.Config {
AutoprovisionAccounts: false,
EnableBasicAuth: false,
InsecureBackends: false,
CSPConfigFileLocation: "",
}
}

Expand Down
52 changes: 52 additions & 0 deletions services/proxy/pkg/middleware/security.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package middleware

import (
"github.com/owncloud/ocis/v2/services/proxy/pkg/config"
"github.com/unrolled/secure"
"github.com/unrolled/secure/cspbuilder"
"gopkg.in/yaml.v2"
"net/http"
"os"
)

// LoadCSPConfig loads CSP header configuration from a yaml file.
func LoadCSPConfig(proxyCfg *config.Config) (*config.CSP, error) {
yamlContent, err := loadCSPYaml(proxyCfg)
if err != nil {
return nil, err
}
cspConfig := config.CSP{}
err = yaml.Unmarshal(yamlContent, &cspConfig)
if err != nil {
return nil, err
}

return &cspConfig, nil
}

func loadCSPYaml(proxyCfg *config.Config) ([]byte, error) {
if proxyCfg.CSPConfigFileLocation == "" {
return []byte(config.DefaultCSPConfig), nil
}
return os.ReadFile(proxyCfg.CSPConfigFileLocation)
}

// Security is a middleware to apply security relevant http headers like CSP.
func Security(cspConfig *config.CSP) func(h http.Handler) http.Handler {
cspBuilder := cspbuilder.Builder{
Directives: cspConfig.Directives,
}

secureMiddleware := secure.New(secure.Options{
BrowserXssFilter: true,
ContentSecurityPolicy: cspBuilder.MustBuild(),
ContentTypeNosniff: true,
CustomFrameOptionsValue: "SAMEORIGIN",
ReferrerPolicy: "strict-origin-when-cross-origin",
STSSeconds: 315360000,
STSPreload: true,
})
return func(next http.Handler) http.Handler {
return secureMiddleware.Handler(next)
}
}
27 changes: 27 additions & 0 deletions vendor/github.com/unrolled/secure/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions vendor/github.com/unrolled/secure/.golangci.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions vendor/github.com/unrolled/secure/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions vendor/github.com/unrolled/secure/Makefile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9ae23ee

Please sign in to comment.