aboutsummaryrefslogtreecommitdiffstats
path: root/web/web.go
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-14 09:20:40 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-14 09:20:40 -0800
commit08032aab10f0e1429d25ecae1acf6c40d63e9ff4 (patch)
treeb4f89ec2deabb7c6bc3237d300512f1af92ea67c /web/web.go
parent17117617017aba1f29a1f6c8939cdc7c1fd94438 (diff)
downloadneko-08032aab10f0e1429d25ecae1acf6c40d63e9ff4.tar.gz
neko-08032aab10f0e1429d25ecae1acf6c40d63e9ff4.tar.bz2
neko-08032aab10f0e1429d25ecae1acf6c40d63e9ff4.zip
security: add HTTP security headers (fixing NK-7xuajb)
Diffstat (limited to 'web/web.go')
-rw-r--r--web/web.go18
1 files changed, 17 insertions, 1 deletions
diff --git a/web/web.go b/web/web.go
index 4868577..11a5831 100644
--- a/web/web.go
+++ b/web/web.go
@@ -259,7 +259,7 @@ func NewRouter(cfg *config.Settings) http.Handler {
mux.Handle("/", GzipMiddleware(AuthWrap(http.HandlerFunc(indexHandler))))
- return CSRFMiddleware(mux)
+ return SecurityHeadersMiddleware(CSRFMiddleware(mux))
}
func Serve(cfg *config.Settings) {
@@ -383,3 +383,19 @@ func CSRFMiddleware(next http.Handler) http.Handler {
next.ServeHTTP(w, r)
})
}
+
+func SecurityHeadersMiddleware(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("X-Content-Type-Options", "nosniff")
+ w.Header().Set("X-Frame-Options", "DENY")
+ w.Header().Set("X-XSS-Protection", "1; mode=block")
+ w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
+ // Content-Security-Policy
+ // default-src 'self'
+ // style-src 'self' 'unsafe-inline' (for React/styled-components if used)
+ // img-src 'self' data: * (RSS images can be from anywhere)
+ // connect-src 'self' (API calls)
+ w.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: *; connect-src 'self'; frame-ancestors 'none';")
+ next.ServeHTTP(w, r)
+ })
+}