fix: Add headers to requests for files in img/ folder to prevent stored xss attacks

A modern browser will see these headers and protect the user by not allowing any code to run.
This commit is contained in:
IRHM
2026-07-05 19:15:05 +01:00
committed by momi
parent 3fe2d2b155
commit 34f7f54e72
2 changed files with 46 additions and 2 deletions
+44
View File
@@ -0,0 +1,44 @@
// This router simply serves the images stored in the server data folder
// under the `img` folder.
// Note: The `img` folder contains user uploaded content (eg profile pictures).
package img
import (
"path"
"github.com/gin-gonic/gin"
"github.com/sbondCo/Watcharr/config"
"github.com/sbondCo/Watcharr/router"
)
type Router struct {
br *router.BaseRouter
}
func NewRouter(br *router.BaseRouter) *Router {
return &Router{
br,
}
}
func (r *Router) AddRoutes() {
img := r.br.Router.Group("/img").
Use(func(c *gin.Context) {
// The two following headers are preventative since this group
// (the static route below) hosts user uploaded content, which can
// potentially include malicious data. We are trying to protect
// against XSS attacks here by telling the browser to:
// - Not sniff content; and
// - Not execute JS; and
// - treat the content as if it was a separate domain (so if eg
// somehow js runs, it won't be in same context as our tokens).
// RESOURCE: web.dev/articles/securely-hosting-user-data
c.Header("X-Content-Type-Options", "nosniff")
c.Header("Content-Security-Policy", "default-src 'none'; sandbox")
c.Next()
})
// Serve up img folder.
img.Static("/", path.Join(config.DataPath, "img"))
}
+2 -2
View File
@@ -33,6 +33,7 @@ import (
"github.com/sbondCo/Watcharr/feature/feature"
"github.com/sbondCo/Watcharr/feature/follow"
"github.com/sbondCo/Watcharr/feature/game"
"github.com/sbondCo/Watcharr/feature/img"
"github.com/sbondCo/Watcharr/feature/imprt"
"github.com/sbondCo/Watcharr/feature/jellyfin"
"github.com/sbondCo/Watcharr/feature/job"
@@ -266,6 +267,7 @@ func main() {
game.NewRouter(br, gameService, watchedService).AddRoutes()
search.NewRouter(br, searchService, watchedService).AddRoutes()
discover.NewRouter(br, discoverService, watchedService).AddRoutes()
img.NewRouter(br).AddRoutes()
// Only add setup routes if there are no users found in db.
var userCount int64
@@ -281,8 +283,6 @@ func main() {
"error", uresp.Error)
}
api.Static("/img", path.Join(config.DataPath, "img"))
go taskl.SetupTasks(cfg, db)
gine.Run("0.0.0.0:3080")