Files
scriptos fd13e67aef
Release Docker Image / Build & Push Docker Image (release) Failing after 1m30s
Release: v0.1.0-alpha
2026-04-05 16:56:16 +02:00

66 lines
2.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Keywarden - Centralized SSH Key Management and Deployment
// Copyright (C) 2026 Patrick Asmus (scriptos)
// SPDX-License-Identifier: AGPL-3.0-or-later
package security
import (
"net/http"
)
// HeadersMiddleware returns middleware that sets security-relevant HTTP
// response headers on every response.
//
// These headers protect against clickjacking, MIME-sniffing, information
// leakage and other common web attacks. They are set regardless of
// whether TLS is in use.
func HeadersMiddleware() func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h := w.Header()
// Prevent the page from being embedded in an iframe (clickjacking)
h.Set("X-Frame-Options", "DENY")
// Stop browsers from MIME-sniffing the content type
h.Set("X-Content-Type-Options", "nosniff")
// Control what information is sent in the Referer header
h.Set("Referrer-Policy", "strict-origin-when-cross-origin")
// Restrict browser features that are not needed
h.Set("Permissions-Policy", "camera=(), microphone=(), geolocation=(), payment=()")
// Content Security Policy fairly strict but allows inline
// styles/scripts that Tabler and the app currently use.
h.Set("Content-Security-Policy",
"default-src 'self'; "+
"script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; "+
"style-src 'self' 'unsafe-inline'; "+
"img-src 'self' data:; "+
"font-src 'self' data:; "+
"connect-src 'self'; "+
"frame-ancestors 'none'; "+
"form-action 'self'; "+
"base-uri 'self'")
// Opt out of Google FLoC / Topics
h.Set("X-Permitted-Cross-Domain-Policies", "none")
// Cache control for authenticated pages prevent caching of
// sensitive data. Static assets set their own cache headers.
if r.URL.Path != "" && !isStaticAsset(r.URL.Path) {
h.Set("Cache-Control", "no-store, no-cache, must-revalidate, private")
h.Set("Pragma", "no-cache")
}
next.ServeHTTP(w, r)
})
}
}
// isStaticAsset returns true for paths that serve static files.
func isStaticAsset(path string) bool {
return len(path) > 8 && (path[:8] == "/static/" || path[:8] == "/avatar/")
}