From dd57a53310f8498c255de2d4472292acf510798a Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Wed, 11 Mar 2026 17:47:51 +0100 Subject: [PATCH] technical-debt: move unrolled/secure replacement to own org Signed-off-by: Christian Richter --- go.mod | 2 +- go.sum | 4 +- .../github.com/unrolled/secure/.golangci.yaml | 44 +++++----- vendor/github.com/unrolled/secure/README.md | 13 ++- vendor/github.com/unrolled/secure/csp.go | 3 +- .../unrolled/secure/cspbuilder/builder.go | 16 ++-- vendor/github.com/unrolled/secure/secure.go | 80 ++++++++++++++----- vendor/modules.txt | 4 +- 8 files changed, 106 insertions(+), 60 deletions(-) diff --git a/go.mod b/go.mod index b552b227d0..b797177ab3 100644 --- a/go.mod +++ b/go.mod @@ -404,7 +404,7 @@ require ( replace github.com/studio-b12/gowebdav => github.com/kobergj/gowebdav v0.0.0-20250102091030-aa65266db202 -replace github.com/unrolled/secure => github.com/DeepDiver1975/secure v0.0.0-20240611112133-abc838fb797c +replace github.com/unrolled/secure => github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 replace go-micro.dev/v4 => github.com/butonic/go-micro/v4 v4.11.1-0.20241115112658-b5d4de5ed9b3 diff --git a/go.sum b/go.sum index 73d13d13ca..31caea4a56 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,6 @@ github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CiscoM31/godata v1.0.11 h1:w7y8twuW02LdH6mak3/GJ5i0GrCv2IoZUJVqa/g5Yeo= github.com/CiscoM31/godata v1.0.11/go.mod h1:ZMiT6JuD3Rm83HEtiTx4JEChsd25YCrxchKGag/sdTc= -github.com/DeepDiver1975/secure v0.0.0-20240611112133-abc838fb797c h1:ocsNvQ2tNHme4v/lTs17HROamc7mFzZfzWcg4m+UXN0= -github.com/DeepDiver1975/secure v0.0.0-20240611112133-abc838fb797c/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/KimMachineGun/automemlimit v0.7.5 h1:RkbaC0MwhjL1ZuBKunGDjE/ggwAX43DwZrJqVwyveTk= github.com/KimMachineGun/automemlimit v0.7.5/go.mod h1:QZxpHaGOQoYvFhv/r4u3U0JTC2ZcOwbSr11UZF46UBM= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -967,6 +965,8 @@ github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260204102724-10bcda1b3068 github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260204102724-10bcda1b3068/go.mod h1:pzatilMEHZFT3qV7C/X3MqOa3NlRQuYhlRhZTL+hN6Q= github.com/opencloud-eu/reva/v2 v2.42.5 h1:Srhk8++3zJe3KA1u2Vqh4VbmljbblF75DR7t4HW0Kxw= github.com/opencloud-eu/reva/v2 v2.42.5/go.mod h1:U3UaHyAQcutavXyLaLE3UVY5n6t2pRAN9uv09n69lwI= +github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 h1:l2oB/RctH+t8r7QBj5p8thfEHCM/jF35aAY3WQ3hADI= +github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= diff --git a/vendor/github.com/unrolled/secure/.golangci.yaml b/vendor/github.com/unrolled/secure/.golangci.yaml index 392b4b34dc..f9bbd2506b 100644 --- a/vendor/github.com/unrolled/secure/.golangci.yaml +++ b/vendor/github.com/unrolled/secure/.golangci.yaml @@ -1,36 +1,32 @@ run: - timeout: 5m + timeout: 10m + modules-download-mode: readonly + allow-parallel-runners: true linters: enable-all: true disable: - # Deprecated linters - - varcheck - - exhaustivestruct - - ifshort - - structcheck - - golint - - maligned - - interfacer - - nosnakecase - - deadcode - - scopelint - - rowserrcheck - - sqlclosecheck - - structcheck - - wastedassign - # Ignoring - - lll - - varnamelen - paralleltest - - testpackage - - goerr113 + - gochecknoglobals - exhaustruct - - nestif + - wrapcheck + - tagliatelle + - depguard + - ireturn - funlen - - goconst + - varnamelen + - gomnd + - execinquery + - copyloopvar + - intrange + - gocognit + - lll - cyclop - gocyclo - - gocognit + - testpackage + - err113 + - nestif - maintidx - contextcheck + - perfsprint + - exportloopref diff --git a/vendor/github.com/unrolled/secure/README.md b/vendor/github.com/unrolled/secure/README.md index 720d531349..e7e80e20eb 100644 --- a/vendor/github.com/unrolled/secure/README.md +++ b/vendor/github.com/unrolled/secure/README.md @@ -1,4 +1,4 @@ -# Secure [![GoDoc](https://godoc.org/github.com/unrolled/secure?status.svg)](http://godoc.org/github.com/unrolled/secure) [![Test](https://github.com/unrolled/secure/workflows/tests/badge.svg?branch=v1)](https://github.com/unrolled/secure/actions) +# Secure [![GoDoc](https://pkg.go.dev/badge/github.com/unrolled/secure)](http://godoc.org/github.com/unrolled/secure) [![Test](https://github.com/unrolled/secure/actions/workflows/test.yaml/badge.svg)](https://github.com/unrolled/secure/actions) Secure is an HTTP middleware for Go that facilitates some quick security wins. It's a standard net/http [Handler](http://golang.org/pkg/net/http/#Handler), and can be used with many [frameworks](#integration-examples) or directly with Go's net/http package. @@ -68,7 +68,7 @@ s := secure.New(secure.Options{ AllowRequestFunc: nil, // AllowRequestFunc is a custom function type that allows you to determine if the request should proceed or not based on your own custom logic. Default is nil. HostsProxyHeaders: []string{"X-Forwarded-Hosts"}, // HostsProxyHeaders is a set of header keys that may hold a proxied hostname value for the request. SSLRedirect: true, // If SSLRedirect is set to true, then only allow HTTPS requests. Default is false. - SSLTemporaryRedirect: false, // If SSLTemporaryRedirect is true, the a 302 will be used while redirecting. Default is false (301). + SSLTemporaryRedirect: false, // If SSLTemporaryRedirect is true, then a 307 will be used while redirecting. Default is false (301). SSLHost: "ssl.example.com", // SSLHost is the host name that is used to redirect HTTP requests to HTTPS. Default is "", which indicates to use the same host. SSLHostFunc: nil, // SSLHostFunc is a function pointer, the return value of the function is the host name that has same functionality as `SSHost`. Default is nil. If SSLHostFunc is nil, the `SSLHost` option will be used. SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"}, // SSLProxyHeaders is set of header keys with associated values that would indicate a valid HTTPS request. Useful when using Nginx: `map[string]string{"X-Forwarded-Proto": "https"}`. Default is blank map. @@ -86,7 +86,10 @@ s := secure.New(secure.Options{ FeaturePolicy: "vibrate 'none';", // Deprecated: this header has been renamed to PermissionsPolicy. FeaturePolicy allows the Feature-Policy header with the value to be set with a custom value. Default is "". PermissionsPolicy: "fullscreen=(), geolocation=()", // PermissionsPolicy allows the Permissions-Policy header with the value to be set with a custom value. Default is "". CrossOriginOpenerPolicy: "same-origin", // CrossOriginOpenerPolicy allows the Cross-Origin-Opener-Policy header with the value to be set with a custom value. Default is "". - + CrossOriginEmbedderPolicy: "require-corp", // CrossOriginEmbedderPolicy allows the Cross-Origin-Embedder-Policy header with the value to be set with a custom value. Default is "". + CrossOriginResourcePolicy: "same-origin", // CrossOriginResourcePolicy allows the Cross-Origin-Resource-Policy header with the value to be set with a custom value. Default is "". + XDNSPrefetchControl: "on", // XDNSPrefetchControl allows the X-DNS-Prefetch-Control header to be set via "on" or "off" keyword. Default is "". + XPermittedCrossDomainPolicies: "none", // XPermittedCrossDomainPolicies allows the X-Permitted-Cross-Domain-Policies to be set with a custom value. Default is "". IsDevelopment: true, // This will cause the AllowedHosts, SSLRedirect, and STSSeconds/STSIncludeSubdomains options to be ignored during development. When deploying to production, be sure to set this to false. }) // ... @@ -123,6 +126,10 @@ l := secure.New(secure.Options{ FeaturePolicy: "", PermissionsPolicy: "", CrossOriginOpenerPolicy: "", + CrossOriginEmbedderPolicy: "", + CrossOriginResourcePolicy: "", + XDNSPrefetchControl: "", + XPermittedCrossDomainPolicies: "", IsDevelopment: false, }) ~~~ diff --git a/vendor/github.com/unrolled/secure/csp.go b/vendor/github.com/unrolled/secure/csp.go index 948358f0b8..4d516c2c34 100644 --- a/vendor/github.com/unrolled/secure/csp.go +++ b/vendor/github.com/unrolled/secure/csp.go @@ -12,7 +12,8 @@ type key int const cspNonceKey key = iota -// CSPNonce returns the nonce value associated with the present request. If no nonce has been generated it returns an empty string. +// CSPNonce returns the nonce value associated with the present request. +// If no nonce has been generated it returns an empty string. func CSPNonce(c context.Context) string { if val, ok := c.Value(cspNonceKey).(string); ok { return val diff --git a/vendor/github.com/unrolled/secure/cspbuilder/builder.go b/vendor/github.com/unrolled/secure/cspbuilder/builder.go index 904203f637..685ab5ff99 100644 --- a/vendor/github.com/unrolled/secure/cspbuilder/builder.go +++ b/vendor/github.com/unrolled/secure/cspbuilder/builder.go @@ -45,7 +45,7 @@ const ( ) type Builder struct { - Directives map[string][]string + Directives map[string]([]string) } // MustBuild is like Build but panics if an error occurs. @@ -61,16 +61,18 @@ func (builder *Builder) MustBuild() string { // Build creates a content security policy string from the specified directives. // If any directive contains invalid values, an error is returned instead. func (builder *Builder) Build() (string, error) { - keys := make([]string, 0, len(builder.Directives)) + var sb strings.Builder - for k := range builder.Directives { - keys = append(keys, k) + // Pull the directive keys out. + directiveKeys := []string{} + for key := range builder.Directives { + directiveKeys = append(directiveKeys, key) } - sort.Strings(keys) + // Sort the policies: https://www.w3.org/TR/CSP3/#framework-policy + sort.Strings(directiveKeys) - var sb strings.Builder - for _, directive := range keys { + for _, directive := range directiveKeys { if sb.Len() > 0 { sb.WriteString("; ") } diff --git a/vendor/github.com/unrolled/secure/secure.go b/vendor/github.com/unrolled/secure/secure.go index 15218e3beb..4f56c265cc 100644 --- a/vendor/github.com/unrolled/secure/secure.go +++ b/vendor/github.com/unrolled/secure/secure.go @@ -12,26 +12,31 @@ import ( type secureCtxKey string const ( - stsHeader = "Strict-Transport-Security" - stsSubdomainString = "; includeSubDomains" - stsPreloadString = "; preload" - frameOptionsHeader = "X-Frame-Options" - frameOptionsValue = "DENY" - contentTypeHeader = "X-Content-Type-Options" - contentTypeValue = "nosniff" - xssProtectionHeader = "X-XSS-Protection" - xssProtectionValue = "1; mode=block" - cspHeader = "Content-Security-Policy" - cspReportOnlyHeader = "Content-Security-Policy-Report-Only" - referrerPolicyHeader = "Referrer-Policy" - featurePolicyHeader = "Feature-Policy" - permissionsPolicyHeader = "Permissions-Policy" - coopHeader = "Cross-Origin-Opener-Policy" + stsHeader = "Strict-Transport-Security" + stsSubdomainString = "; includeSubDomains" + stsPreloadString = "; preload" + frameOptionsHeader = "X-Frame-Options" + frameOptionsValue = "DENY" + contentTypeHeader = "X-Content-Type-Options" + contentTypeValue = "nosniff" + xssProtectionHeader = "X-XSS-Protection" + xssProtectionValue = "1; mode=block" + cspHeader = "Content-Security-Policy" + cspReportOnlyHeader = "Content-Security-Policy-Report-Only" + hpkpHeader = "Public-Key-Pins" + referrerPolicyHeader = "Referrer-Policy" + featurePolicyHeader = "Feature-Policy" + permissionsPolicyHeader = "Permissions-Policy" + coopHeader = "Cross-Origin-Opener-Policy" + coepHeader = "Cross-Origin-Embedder-Policy" + corpHeader = "Cross-Origin-Resource-Policy" + dnsPreFetchControlHeader = "X-DNS-Prefetch-Control" + permittedCrossDomainPolicies = "X-Permitted-Cross-Domain-Policies" robotTagHeader = "X-Robots-Tag" permittedCrossDomainPoliciesHeader = "X-Permitted-Cross-Domain-Policies" - ctxDefaultSecureHeaderKey = secureCtxKey("SecureResponseHeader") - cspNonceSize = 16 + ctxDefaultSecureHeaderKey = secureCtxKey("SecureResponseHeader") + cspNonceSize = 16 ) // SSLHostFunc is a custom function type that can be used to dynamically set the SSL host of a request. @@ -67,7 +72,7 @@ type Options struct { SSLRedirect bool // If SSLForceHost is true and SSLHost is set, requests will be forced to use SSLHost even the ones that are already using SSL. Default is false. SSLForceHost bool - // If SSLTemporaryRedirect is true, a 302 will be used while redirecting. Default is false (301). + // If SSLTemporaryRedirect is true, then a 307 will be used while redirecting. Default is false (301). SSLTemporaryRedirect bool // If STSIncludeSubdomains is set to true, the `includeSubdomains` will be appended to the Strict-Transport-Security header. Default is false. STSIncludeSubdomains bool @@ -93,6 +98,18 @@ type Options struct { // CrossOriginOpenerPolicy allows you to ensure a top-level document does not share a browsing context group with cross-origin documents. Default is "". // Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy CrossOriginOpenerPolicy string + // CrossOriginResourcePolicy header blocks others from loading your resources cross-origin in some cases. + // Reference https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy + CrossOriginResourcePolicy string + // CrossOriginEmbedderPolicy header helps control what resources can be loaded cross-origin. + // Reference https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy + CrossOriginEmbedderPolicy string + // XDNSPrefetchControl header helps control DNS prefetching, which can improve user privacy at the expense of performance. + // Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control + XDNSPrefetchControl string + // XPermittedCrossDomainPolicies header tells some clients (mostly Adobe products) your domain's policy for loading cross-domain content. + // Reference: https://owasp.org/www-project-secure-headers/ + XPermittedCrossDomainPolicies string // SSLHost is the host name that is used to redirect http requests to https. Default is "", which indicates to use the same host. SSLHost string // AllowedHosts is a slice of fully qualified domain names that are allowed. Default is an empty slice, which allows any and all host names. @@ -100,12 +117,12 @@ type Options struct { // AllowedHostsAreRegex determines, if the provided `AllowedHosts` slice contains valid regular expressions. If this flag is set to true, every request's host will be checked against these expressions. Default is false. AllowedHostsAreRegex bool // AllowRequestFunc is a custom function that allows you to determine if the request should proceed or not based on your own custom logic. Default is nil. - AllowRequestFunc AllowRequestFunc + AllowRequestFunc AllowRequestFunc `json:"-" toml:"-" yaml:"-"` // HostsProxyHeaders is a set of header keys that may hold a proxied hostname value for the request. HostsProxyHeaders []string // SSLHostFunc is a function pointer, the return value of the function is the host name that has same functionality as `SSHost`. Default is nil. // If SSLHostFunc is nil, the `SSLHost` option will be used. - SSLHostFunc *SSLHostFunc + SSLHostFunc *SSLHostFunc `json:"-" toml:"-" yaml:"-"` // SSLProxyHeaders is set of header keys with associated values that would indicate a valid https request. Useful when using Nginx: `map[string]string{"X-Forwarded-Proto": "https"}`. Default is blank map. SSLProxyHeaders map[string]string // STSSeconds is the max-age of the Strict-Transport-Security header. Default is 0, which would NOT include the header. @@ -474,6 +491,29 @@ func (s *Secure) processRequest(w http.ResponseWriter, r *http.Request) (http.He responseHeader.Set(coopHeader, s.opt.CrossOriginOpenerPolicy) } + // Cross Origin Resource Policy header. + if len(s.opt.CrossOriginResourcePolicy) > 0 { + responseHeader.Set(corpHeader, s.opt.CrossOriginResourcePolicy) + } + + // Cross-Origin-Embedder-Policy header. + if len(s.opt.CrossOriginEmbedderPolicy) > 0 { + responseHeader.Set(coepHeader, s.opt.CrossOriginEmbedderPolicy) + } + + // X-DNS-Prefetch-Control header. + switch strings.ToLower(s.opt.XDNSPrefetchControl) { + case "on": + responseHeader.Set(dnsPreFetchControlHeader, "on") + case "off": + responseHeader.Set(dnsPreFetchControlHeader, "off") + } + + // X-Permitted-Cross-Domain-Policies header. + if len(s.opt.XPermittedCrossDomainPolicies) > 0 { + responseHeader.Set(permittedCrossDomainPolicies, s.opt.XPermittedCrossDomainPolicies) + } + // X-Permitted-Cross-Domain-Policies if len(s.opt.PermittedCrossDomainPolicies) > 0 { responseHeader.Set(permittedCrossDomainPoliciesHeader, s.opt.PermittedCrossDomainPolicies) diff --git a/vendor/modules.txt b/vendor/modules.txt index 07156be974..67256f216d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -2154,7 +2154,7 @@ github.com/trustelem/zxcvbn/scoring # github.com/tus/tusd/v2 v2.8.0 ## explicit; go 1.23.0 github.com/tus/tusd/v2/pkg/handler -# github.com/unrolled/secure v1.16.0 => github.com/DeepDiver1975/secure v0.0.0-20240611112133-abc838fb797c +# github.com/unrolled/secure v1.16.0 => github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 ## explicit; go 1.13 github.com/unrolled/secure github.com/unrolled/secure/cspbuilder @@ -2756,6 +2756,6 @@ sigs.k8s.io/yaml ## explicit; go 1.13 stash.kopano.io/kgol/rndm # github.com/studio-b12/gowebdav => github.com/kobergj/gowebdav v0.0.0-20250102091030-aa65266db202 -# github.com/unrolled/secure => github.com/DeepDiver1975/secure v0.0.0-20240611112133-abc838fb797c +# github.com/unrolled/secure => github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 # go-micro.dev/v4 => github.com/butonic/go-micro/v4 v4.11.1-0.20241115112658-b5d4de5ed9b3 # github.com/go-micro/plugins/v4/store/nats-js-kv => github.com/opencloud-eu/go-micro-plugins/v4/store/nats-js-kv v0.0.0-20250512152754-23325793059a