diff --git a/Makefile b/Makefile index 7cf1327f..bcbc1541 100644 --- a/Makefile +++ b/Makefile @@ -17,3 +17,4 @@ build_plugins: go build -buildmode=plugin -o ./dist/data/plugin/backend_mysql.so server/plugin/plg_backend_mysql/index.go go build -buildmode=plugin -o dist/data/plugin/backend_backblaze.so server/plugin/plg_backend_backblaze/index.go go build -buildmode=plugin -o dist/data/plugin/security_scanner.so server/plugin/plg_security_scanner/index.go + go build -buildmode=plugin -o dist/data/plugin/security_svg.so server/plugin/plg_security_svg/index.go diff --git a/server/ctrl/files.go b/server/ctrl/files.go index b419455f..229cb1e7 100644 --- a/server/ctrl/files.go +++ b/server/ctrl/files.go @@ -235,7 +235,9 @@ func FileCat(ctx App, res http.ResponseWriter, req *http.Request) { header.Set("Content-Length", fmt.Sprintf("%d", contentLength)) } header.Set("Content-Type", GetMimeType(req.URL.Query().Get("path"))) - header.Set("Content-Security-Policy", "script-src 'none'") + if header.Get("Content-Security-Policy") == "" { + header.Set("Content-Security-Policy", "default-src 'none'; img-src 'self'; style-src 'unsafe-inline'") + } header.Set("Accept-Ranges", "bytes") // Send data to the client diff --git a/server/plugin/plg_security_svg/index.go b/server/plugin/plg_security_svg/index.go new file mode 100644 index 00000000..67a7cb71 --- /dev/null +++ b/server/plugin/plg_security_svg/index.go @@ -0,0 +1,44 @@ +package main + +import ( + . "github.com/mickael-kerjean/filestash/server/common" + "io" + "io/ioutil" + "net/http" + "regexp" +) + +func Init(conf *Configuration) { + disable_svg := func() bool { + return conf.Get("features.protection.disable_svg").Schema(func(f *FormElement) *FormElement { + if f == nil { + f = &FormElement{} + } + f.Default = true + f.Name = "disable_svg" + f.Type = "boolean" + f.Target = []string{} + f.Description = "Disable the display of SVG documents" + f.Placeholder = "Default: true" + return f + }).Bool() + } + disable_svg() + + Hooks.Register.ProcessFileContentBeforeSend(func (reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error){ + if GetMimeType(req.URL.Query().Get("path")) != "image/svg+xml" { + return reader, nil + } else if disable_svg() == true { + return reader, ErrNotAllowed + } + + // XSS + (*res).Header().Set("Content-Security-Policy", "script-src 'none'; default-src 'none'; img-src 'self'") + // XML bomb + txt, _ := ioutil.ReadAll(reader) + if regexp.MustCompile("(?is)entity").Match(txt) { + txt = []byte("") + } + return NewReadCloserFromBytes(txt), nil + }) +}