Skip to content

Commit

Permalink
feat: add secure middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
micbar committed Jan 22, 2024
1 parent 1cb5fb9 commit 2accf58
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 8 deletions.
70 changes: 70 additions & 0 deletions internal/http/interceptors/secure/secure.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package secure

import (
"net/http"

"github.com/cs3org/reva/v2/pkg/rhttp/global"
"github.com/mitchellh/mapstructure"
)

const (
defaultPriority = 200
)

func init() {
global.RegisterMiddleware("secure", New)
}

type secure struct {
ContentSecurityPolicy string `mapstructure:"content_security_policy"`
Priority int `mapstructure:"priority"`
}

// New creates a new secure middleware.
func New(m map[string]interface{}) (global.Middleware, int, error) {
s := &secure{}
if err := mapstructure.Decode(m, s); err != nil {
return nil, 0, err
}

if s.Priority == 0 {
s.Priority = defaultPriority
}

if s.ContentSecurityPolicy == "" {
s.ContentSecurityPolicy = "frame-ancestors 'none'"
}

return s.Handler, s.Priority, nil
}

// Handler is the middleware function.
func (m *secure) Handler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Indicates whether the browser is allowed to render this page in a <frame>, <iframe>, <embed> or <object>.
w.Header().Set("X-Frame-Options", "DENY")
// Does basically the same as X-Frame-Options.
w.Header().Set("Content-Security-Policy", m.ContentSecurityPolicy)
// This header inidicates that MIME types advertised in the Content-Type headers should not be changed and be followed.
w.Header().Set("X-Content-Type-Options", "nosniff")
// Disallow iFraming from other domains
w.Header().Set("X-Frame-Options", "SAMEORIGIN")
// https://msdn.microsoft.com/en-us/library/jj542450(v=vs.85).aspx
w.Header().Set("X-Download-Options", "noopen")
// Disallow iFraming from other domains
w.Header().Set("X-Frame-Options", "SAMEORIGIN")
// https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html
w.Header().Set("X-Permitted-Cross-Domain-Policies", "none")
// https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag
w.Header().Set("X-Robots-Tag", "none")
// enforce browser based XSS filters
w.Header().Set("X-XSS-Protection", "1; mode=block")

if r.TLS != nil {
// Tell browsers that the website should only be accessed using HTTPS.
w.Header().Set("Strict-Transport-Security", "max-age=31536000")
}

next.ServeHTTP(w, r)
})
}
22 changes: 15 additions & 7 deletions pkg/micro/ocdav/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,14 @@ type Options struct {
MetricsSubsystem string

// ocdav.* is internal so we need to set config options individually
config config.Config
lockSystem ocdav.LockSystem
AllowCredentials bool
AllowedOrigins []string
AllowedHeaders []string
AllowedMethods []string
AllowDepthInfinity bool
config config.Config
lockSystem ocdav.LockSystem
AllowCredentials bool
AllowedOrigins []string
AllowedHeaders []string
AllowedMethods []string
AllowDepthInfinity bool
ContentSecurityPolicy string
}

// newOptions initializes the available default options.
Expand Down Expand Up @@ -350,6 +351,13 @@ func AllowedHeaders(val []string) Option {
}
}

// ContentSecurityPolicy provides a function to set the ContentSecurityPolicy option.
func ContentSecurityPolicy(val string) Option {
return func(o *Options) {
o.ContentSecurityPolicy = val
}
}

// ItemNameInvalidChars provides a function to set forbidden characters in file or folder names
func ItemNameInvalidChars(chars []string) Option {
return func(o *Options) {
Expand Down
7 changes: 6 additions & 1 deletion pkg/micro/ocdav/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/cs3org/reva/v2/internal/http/interceptors/auth"
cors2 "github.com/cs3org/reva/v2/internal/http/interceptors/cors"
revaLogMiddleware "github.com/cs3org/reva/v2/internal/http/interceptors/log"
secure2 "github.com/cs3org/reva/v2/internal/http/interceptors/secure"
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/rhttp/global"
Expand Down Expand Up @@ -225,8 +226,12 @@ func useMiddlewares(r *chi.Mux, sopts *Options, svc global.Service, tp trace.Tra
// request-id
rm := middleware.RequestID

secure, _, err := secure2.New(map[string]interface{}{

Check failure on line 229 in pkg/micro/ocdav/service.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to err (ineffassign)
"content_security_policy": sopts.ContentSecurityPolicy,
})

// actually register
r.Use(pm, tm, lm, authMiddle, rm, cm, cors)
r.Use(pm, tm, lm, authMiddle, rm, cm, cors, secure)
return nil
}

Expand Down

0 comments on commit 2accf58

Please sign in to comment.