diff --git a/cmd/info.go b/cmd/info.go index 9d81066..c59715b 100644 --- a/cmd/info.go +++ b/cmd/info.go @@ -21,6 +21,8 @@ func serveExtensions(formats types.Types, available bool, errorChannel chan<- er return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { startTime := time.Now() + w.Header().Add("Content-Security-Policy", "default-src 'self';") + w.Header().Set("Content-Type", "text/plain;charset=UTF-8") var extensions string @@ -51,14 +53,16 @@ func serveIndex(args []string, index *fileIndex, errorChannel chan<- error) http return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { startTime := time.Now() + w.Header().Add("Content-Security-Policy", "default-src 'self';") + + w.Header().Set("Content-Type", "application/json;charset=UTF-8") + indexDump := index.List() sort.SliceStable(indexDump, func(p, q int) bool { return strings.ToLower(indexDump[p]) < strings.ToLower(indexDump[q]) }) - w.Header().Set("Content-Type", "application/json;charset=UTF-8") - response, err := json.MarshalIndent(indexDump, "", " ") if err != nil { errorChannel <- err @@ -90,10 +94,12 @@ func serveIndexRebuild(args []string, index *fileIndex, formats types.Types, enc return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { startTime := time.Now() - rebuildIndex(args, index, formats, encoder, errorChannel) + w.Header().Add("Content-Security-Policy", "default-src 'self';") w.Header().Set("Content-Type", "text/plain;charset=UTF-8") + rebuildIndex(args, index, formats, encoder, errorChannel) + _, err := w.Write([]byte("Ok\n")) if err != nil { errorChannel <- err @@ -115,6 +121,8 @@ func serveMediaTypes(formats types.Types, available bool, errorChannel chan<- er return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { startTime := time.Now() + w.Header().Add("Content-Security-Policy", "default-src 'self';") + w.Header().Set("Content-Type", "text/plain;charset=UTF-8") var mediaTypes string diff --git a/cmd/root.go b/cmd/root.go index 37d470e..cf0e9f3 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -17,7 +17,7 @@ import ( const ( AllowedCharacters string = `^[A-z0-9.\-_]+$` - ReleaseVersion string = "8.1.0" + ReleaseVersion string = "8.2.0" ) var ( diff --git a/cmd/web.go b/cmd/web.go index 5ebe9a3..de0ccd6 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -55,6 +55,8 @@ func newPage(title, body, nonce string) string { func serveStaticFile(paths []string, index *fileIndex, errorChannel chan<- error) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + w.Header().Add("Content-Security-Policy", "default-src 'self';") + prefix := Prefix + sourcePrefix path := strings.TrimPrefix(r.URL.Path, prefix) @@ -157,6 +159,8 @@ func serveStaticFile(paths []string, index *fileIndex, errorChannel chan<- error func serveRoot(paths []string, index *fileIndex, filename *regexp.Regexp, formats types.Types, encoder *zstd.Encoder, errorChannel chan<- error) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + w.Header().Add("Content-Security-Policy", "default-src 'self';") + refererUri, err := stripQueryParams(refererToUri(r.Referer())) if err != nil { errorChannel <- err @@ -423,6 +427,8 @@ func serveVersion(errorChannel chan<- error) httprouter.Handle { data := []byte(fmt.Sprintf("roulette v%s\n", ReleaseVersion)) + w.Header().Add("Content-Security-Policy", "default-src 'self';") + w.Header().Set("Content-Type", "text/plain;charset=UTF-8") w.Header().Set("Content-Length", strconv.Itoa(len(data))) diff --git a/types/audio/audio.go b/types/audio/audio.go index 6d98d8f..f5aa99d 100644 --- a/types/audio/audio.go +++ b/types/audio/audio.go @@ -15,7 +15,11 @@ import ( type Format struct{} func (t Format) CSP(w http.ResponseWriter) string { - return "" + nonce := types.GetNonce(6) + + w.Header().Add("Content-Security-Policy", fmt.Sprintf("default-src 'self' 'nonce-%s';", nonce)) + + return nonce } func (t Format) CSS() string { diff --git a/types/code/code.go b/types/code/code.go index 0cdee19..2bd05df 100644 --- a/types/code/code.go +++ b/types/code/code.go @@ -26,7 +26,11 @@ type Format struct { } func (t Format) CSP(w http.ResponseWriter) string { - return "" + nonce := types.GetNonce(6) + + w.Header().Add("Content-Security-Policy", fmt.Sprintf("default-src 'self' 'nonce-%s'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';", nonce)) + + return nonce } func (t Format) CSS() string { diff --git a/types/flash/flash.go b/types/flash/flash.go index 7f5f4e9..d66d012 100644 --- a/types/flash/flash.go +++ b/types/flash/flash.go @@ -15,7 +15,11 @@ import ( type Format struct{} func (t Format) CSP(w http.ResponseWriter) string { - return "" + nonce := types.GetNonce(6) + + w.Header().Add("Content-Security-Policy", fmt.Sprintf("default-src 'self' 'nonce-%s'; script-src 'self' 'unsafe-inline'", nonce)) + + return nonce } func (t Format) CSS() string { diff --git a/types/text/text.go b/types/text/text.go index 86023fe..4a98dcd 100644 --- a/types/text/text.go +++ b/types/text/text.go @@ -18,7 +18,11 @@ import ( type Format struct{} func (t Format) CSP(w http.ResponseWriter) string { - return "" + nonce := types.GetNonce(6) + + w.Header().Add("Content-Security-Policy", fmt.Sprintf("default-src 'self' 'nonce-%s';", nonce)) + + return nonce } func (t Format) CSS() string { diff --git a/types/video/video.go b/types/video/video.go index c69d70c..60d35c2 100644 --- a/types/video/video.go +++ b/types/video/video.go @@ -16,7 +16,11 @@ import ( type Format struct{} func (t Format) CSP(w http.ResponseWriter) string { - return "" + nonce := types.GetNonce(6) + + w.Header().Add("Content-Security-Policy", fmt.Sprintf("default-src 'self' 'nonce-%s';", nonce)) + + return nonce } func (t Format) CSS() string { @@ -35,8 +39,9 @@ func (t Format) Title(rootUrl, fileUri, filePath, fileName, prefix, mime string) } func (t Format) Body(rootUrl, fileUri, filePath, fileName, prefix, mime, nonce string) (string, error) { - return fmt.Sprintf(``, + return fmt.Sprintf(``, rootUrl, + nonce, fileUri, mime, fileName), nil