@@ -37,6 +37,42 @@ type ServeHeaderOptions struct {
3737 LastModified time.Time
3838}
3939
40+ const (
41+ // Disable JS execution on the same origin, since we serve the file from the same origin as Gitea server.
42+ // This rule can be relaxed in the future as long as it is properly sandboxed.
43+ // "style-src" is for SVG inline styles (from Display SVG files as images instead of text #14101)
44+ serveHeaderCspDefault = "default-src 'none'; style-src 'unsafe-inline'; sandbox"
45+
46+ // No sandbox attribute for PDF as it breaks rendering in at least Safari.
47+ // This should generally be safe as scripts inside PDF can not escape the PDF document.
48+ // See https://bugs.chromium.org/p/chromium/issues/detail?id=413851 for more discussion.
49+ // HINT: PDF-RENDER-SANDBOX: PDF won't render in sandboxed context
50+ serveHeaderCspPdf = "default-src 'none'; style-src 'unsafe-inline'"
51+
52+ // For audios and videos, actually it doesn't really need CSP (just like Gitea <= 1.25)
53+ serveHeaderCspAudioVideo = ""
54+ )
55+
56+ func serveSetHeaderContentRelated (w http.ResponseWriter , contentType string ) {
57+ header := w .Header ()
58+ contentType = util .IfZero (contentType , typesniffer .MimeTypeApplicationOctetStream )
59+ header .Set ("Content-Type" , contentType )
60+ header .Set ("X-Content-Type-Options" , "nosniff" )
61+
62+ csp := serveHeaderCspDefault
63+ if strings .HasPrefix (contentType , "application/pdf" ) {
64+ csp = serveHeaderCspPdf
65+ }
66+ if strings .HasPrefix (contentType , "video/" ) || strings .HasPrefix (contentType , "audio/" ) {
67+ csp = serveHeaderCspAudioVideo
68+ }
69+ if csp != "" {
70+ header .Set ("Content-Security-Policy" , csp )
71+ } else {
72+ header .Del ("Content-Security-Policy" )
73+ }
74+ }
75+
4076// ServeSetHeaders sets necessary content serve headers
4177func ServeSetHeaders (w http.ResponseWriter , opts ServeHeaderOptions ) {
4278 header := w .Header ()
@@ -46,24 +82,11 @@ func ServeSetHeaders(w http.ResponseWriter, opts ServeHeaderOptions) {
4682 w .Header ().Add (gzhttp .HeaderNoCompression , "1" )
4783 }
4884
49- contentType := util .IfZero (opts .ContentType , typesniffer .MimeTypeApplicationOctetStream )
50- header .Set ("Content-Type" , contentType )
51- header .Set ("X-Content-Type-Options" , "nosniff" )
85+ serveSetHeaderContentRelated (w , opts .ContentType )
5286
5387 if opts .ContentLength != nil {
5488 header .Set ("Content-Length" , strconv .FormatInt (* opts .ContentLength , 10 ))
5589 }
56-
57- // Disable script execution of HTML/SVG files, since we serve the file from the same origin as Gitea server
58- header .Set ("Content-Security-Policy" , "default-src 'none'; style-src 'unsafe-inline'; sandbox" )
59- if strings .Contains (contentType , "application/pdf" ) {
60- // no sandbox attribute for PDF as it breaks rendering in at least safari. this
61- // should generally be safe as scripts inside PDF can not escape the PDF document
62- // see https://bugs.chromium.org/p/chromium/issues/detail?id=413851 for more discussion
63- // HINT: PDF-RENDER-SANDBOX: PDF won't render in sandboxed context
64- header .Set ("Content-Security-Policy" , "default-src 'none'; style-src 'unsafe-inline'" )
65- }
66-
6790 if opts .Filename != "" && opts .ContentDisposition != "" {
6891 header .Set ("Content-Disposition" , encodeContentDisposition (opts .ContentDisposition , path .Base (opts .Filename )))
6992 header .Set ("Access-Control-Expose-Headers" , "Content-Disposition" )
0 commit comments