1
0
mirror of https://github.com/owncloud/ocis.git synced 2026-10-23 23:29:02 +03:00
Files
ocis/services/proxy/pkg/middleware/security_test.go
Juan Pablo Villafañez 597104629a fix: use specific gookit config instance instance of using global (#12769)
* fix: use specific gookit config instance instance of using global

Using the global instance was causing a panic when the service was
restarted. That panic won't happen now.

* chore: add changelog entry
2026-08-11 17:48:46 +02:00

111 lines
3.5 KiB
Go

package middleware
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/owncloud/ocis/v2/services/proxy/pkg/config"
"gotest.tools/v3/assert"
)
func TestLoadCSPConfig(t *testing.T) {
// setup test env
yaml := `
directives:
frame-src:
- '''self'''
- 'https://embed.diagrams.net/'
- 'https://${ONLYOFFICE_DOMAIN|onlyoffice.owncloud.test}/'
- 'https://${COLLABORA_DOMAIN|collabora.owncloud.test}/'
`
config, err := loadCSPConfig("proxy", []byte(yaml))
if err != nil {
t.Error(err)
}
assert.Equal(t, config.Directives["frame-src"][0], "'self'")
assert.Equal(t, config.Directives["frame-src"][1], "https://embed.diagrams.net/")
assert.Equal(t, config.Directives["frame-src"][2], "https://onlyoffice.owncloud.test/")
assert.Equal(t, config.Directives["frame-src"][3], "https://collabora.owncloud.test/")
}
func TestStrictTransportSecurity(t *testing.T) {
// Create test handler
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
// Use production security middleware config
cspConfig := &config.CSP{
Directives: map[string][]string{
"default-src": {"'none'"},
},
}
cfg := &config.Config{HTTP: config.HTTP{ForceStrictTransportSecurity: false}}
securityMiddleware := Security(cfg, cspConfig)
// Test HTTPS request, url not important, only headers will be checked
req, err := http.NewRequest("GET", "https://example.com", nil)
if err != nil {
t.Fatal(err)
}
req.Header.Set("X-Forwarded-Proto", "https")
rr := httptest.NewRecorder()
securityMiddleware(handler).ServeHTTP(rr, req)
hstsHeader := rr.Header().Get("Strict-Transport-Security")
// HSTS header should contain includeSubDomains
expected := "max-age=315360000; includeSubDomains; preload"
assert.Equal(t, hstsHeader, expected, "HSTS header missing includeSubDomains directive - subdomains not protected")
}
func TestStrictTransportSecurity_ForceOnHTTP(t *testing.T) {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
cspConfig := &config.CSP{
Directives: map[string][]string{
"default-src": {"'none'"},
},
}
cfg := &config.Config{HTTP: config.HTTP{ForceStrictTransportSecurity: true}}
securityMiddleware := Security(cfg, cspConfig)
// Plain HTTP request (no TLS); should still emit Strict-Transport-Security when forced.
req := httptest.NewRequest("GET", "http://example.com/", nil)
rr := httptest.NewRecorder()
securityMiddleware(handler).ServeHTTP(rr, req)
stsHeader := rr.Header().Get("Strict-Transport-Security")
expected := "max-age=315360000; includeSubDomains; preload"
assert.Equal(t, stsHeader, expected)
}
func TestXXSSProtection(t *testing.T) {
// Reference: Penetration test audit Section 2.2, Table 2 Row 3
// X-XSS-Protection header must be explicitly set to "0" to disable
// the deprecated browser XSS filter which can introduce vulnerabilities
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
cspConfig := &config.CSP{
Directives: map[string][]string{
"default-src": {"'none'"},
},
}
cfg := &config.Config{HTTP: config.HTTP{ForceStrictTransportSecurity: false}}
securityMiddleware := Security(cfg, cspConfig)
req := httptest.NewRequest("GET", "https://example.com/", nil)
rr := httptest.NewRecorder()
securityMiddleware(handler).ServeHTTP(rr, req)
xssHeader := rr.Header().Get("X-XSS-Protection")
expected := "0"
assert.Equal(t, xssHeader, expected, "X-XSS-Protection must be '0' to disable deprecated XSS filter (audit requirement)")
}