mirror of
https://gitea.phreedom.club/localhost_frssoft/bloat.git
synced 2024-11-21 20:29:20 +02:00
Use CSP header to restrict resource loading
This helps mitigate XSS exploits. Users will have to save the settings again to make the custom CSS work.
This commit is contained in:
parent
ed521dd33d
commit
67b13c71ba
|
@ -27,6 +27,7 @@ type Settings struct {
|
|||
AntiDopamineMode bool `json:"adm,omitempty"`
|
||||
HideUnsupportedNotifs bool `json:"hun,omitempty"`
|
||||
CSS string `json:"css,omitempty"`
|
||||
CSSHash string `json:"cssh,omitempty"`
|
||||
}
|
||||
|
||||
func NewSettings() *Settings {
|
||||
|
@ -43,5 +44,6 @@ func NewSettings() *Settings {
|
|||
AntiDopamineMode: false,
|
||||
HideUnsupportedNotifs: false,
|
||||
CSS: "",
|
||||
CSSHash: "",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"mime/multipart"
|
||||
|
@ -1014,8 +1016,18 @@ func (s *service) SaveSettings(c *client, settings *model.Settings) (err error)
|
|||
default:
|
||||
return errInvalidArgument
|
||||
}
|
||||
if len(settings.CSS) > 1<<20 {
|
||||
return errInvalidArgument
|
||||
if len(settings.CSS) > 0 {
|
||||
if len(settings.CSS) > 1<<20 {
|
||||
return errInvalidArgument
|
||||
}
|
||||
// For some reason, browsers convert CRLF to LF before calculating
|
||||
// the hash of the inline resources.
|
||||
settings.CSS = strings.ReplaceAll(settings.CSS, "\x0d\x0a", "\x0a")
|
||||
|
||||
h := sha256.Sum256([]byte(settings.CSS))
|
||||
settings.CSSHash = base64.StdEncoding.EncodeToString(h[:])
|
||||
} else {
|
||||
settings.CSSHash = ""
|
||||
}
|
||||
c.s.Settings = *settings
|
||||
return c.setSession(c.s)
|
||||
|
|
|
@ -26,6 +26,16 @@ const (
|
|||
CSRF
|
||||
)
|
||||
|
||||
const csp = "default-src 'none';" +
|
||||
" img-src *;" +
|
||||
" media-src *;" +
|
||||
" font-src *;" +
|
||||
" child-src *;" +
|
||||
" connect-src 'self';" +
|
||||
" form-action 'self';" +
|
||||
" script-src 'self';" +
|
||||
" style-src 'self'"
|
||||
|
||||
func NewHandler(s *service, verbose bool, staticDir string) http.Handler {
|
||||
r := mux.NewRouter()
|
||||
|
||||
|
@ -58,14 +68,14 @@ func NewHandler(s *service, verbose bool, staticDir string) http.Handler {
|
|||
}(time.Now())
|
||||
}
|
||||
|
||||
var ct string
|
||||
h := c.w.Header()
|
||||
switch rt {
|
||||
case HTML:
|
||||
ct = "text/html; charset=utf-8"
|
||||
h.Set("Content-Type", "text/html; charset=utf-8")
|
||||
h.Set("Content-Security-Policy", csp)
|
||||
case JSON:
|
||||
ct = "application/json"
|
||||
h.Set("Content-Type", "application/json")
|
||||
}
|
||||
c.w.Header().Add("Content-Type", ct)
|
||||
|
||||
err = c.authenticate(at, s.instance)
|
||||
if err != nil {
|
||||
|
@ -73,6 +83,13 @@ func NewHandler(s *service, verbose bool, staticDir string) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
// Override the CSP header to allow custom CSS
|
||||
if rt == HTML && len(c.s.Settings.CSS) > 0 &&
|
||||
len(c.s.Settings.CSSHash) > 0 {
|
||||
v := fmt.Sprintf("%s 'sha256-%s'", csp, c.s.Settings.CSSHash)
|
||||
h.Set("Content-Security-Policy", v)
|
||||
}
|
||||
|
||||
err = f(c)
|
||||
if err != nil {
|
||||
writeError(c, err, rt, req.Method == http.MethodGet)
|
||||
|
|
Loading…
Reference in New Issue