Merge pull request #288 from Molecule-AI/fix/security-headers-referrer-permissions

fix(security): add Referrer-Policy + Permissions-Policy headers (#282)
This commit is contained in:
Hongming Wang 2026-04-15 16:52:37 -07:00 committed by GitHub
commit d340924479
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 0 deletions

View File

@ -9,12 +9,22 @@ import "github.com/gin-gonic/gin"
// - X-Frame-Options: DENY — blocks iframe embedding (clickjacking)
// - Content-Security-Policy: default-src 'self' — restricts resource loading to same origin
// - Strict-Transport-Security: max-age=31536000; includeSubDomains — enforces HTTPS for 1 year
// - Referrer-Policy: strict-origin-when-cross-origin — avoids leaking full paths/queries in Referer
// - Permissions-Policy: camera=(), microphone=(), geolocation=() — denies sensor access for embedded content
func SecurityHeaders() gin.HandlerFunc {
return func(c *gin.Context) {
c.Header("X-Content-Type-Options", "nosniff")
c.Header("X-Frame-Options", "DENY")
c.Header("Content-Security-Policy", "default-src 'self'")
c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
// #282: these two were documented in CLAUDE.md but missing from
// the middleware. Referrer-Policy prevents browsers from leaking
// the full Referer URL to cross-origin resources (which can
// expose internal paths/queries). Permissions-Policy denies
// sensor access by default — especially relevant because the
// canvas embeds iframes for Langfuse traces.
c.Header("Referrer-Policy", "strict-origin-when-cross-origin")
c.Header("Permissions-Policy", "camera=(), microphone=(), geolocation=()")
c.Next()
}
}

View File

@ -35,6 +35,10 @@ func TestSecurityHeaders(t *testing.T) {
{"X-Frame-Options", "DENY"},
{"Content-Security-Policy", "default-src 'self'"},
{"Strict-Transport-Security", "max-age=31536000; includeSubDomains"},
// #282: regression guards for the two headers that were
// documented in CLAUDE.md but missing from the implementation.
{"Referrer-Policy", "strict-origin-when-cross-origin"},
{"Permissions-Policy", "camera=(), microphone=(), geolocation=()"},
}
for _, tt := range tests {