@@ -56,20 +56,35 @@ function readAllInput(input, callback) {
5656 });
5757}
5858
59- function addSecurityHeaders(res, allowScriptsAtStartup) {
60- if (process.env.INSTANT_MARKDOWN_ALLOW_UNSAFE_CONTENT) {
61- return ;
59+ function addSecurityHeaders(req, res, isIndexFile) {
60+ var csp = [];
61+
62+ // Cannot use ' self' because Chrome does not treat ' self' as http://host
63+ // when the sandbox directive is set.
64+ var HTTP_HOST = req.headers.host || ' localhost:8090' ;
65+ var CSP_SELF = ' http://' + HTTP_HOST;
66+
67+ if (! process.env.INSTANT_MARKDOWN_ALLOW_UNSAFE_CONTENT) {
68+ if (isIndexFile) {
69+ // index.html will drop the scripting capabilities upon load.
70+ csp.push(' script-src ' + CSP_SELF + " 'unsafe-inline'" );
71+ csp.push(' sandbox allow-scripts allow-modals allow-forms' );
72+ } else {
73+ csp.push(' script-src ' );
74+ }
6275 }
63-
64- var csp =
65- // index.html will drop the scripting capabilities upon load.
66- " script-src " + (allowScriptsAtStartup ? " 'self' 'unsafe-inline'" : " " ) +
67- " ; sandbox allow-scripts allow-modals allow-forms" ;
6876 if (process.env.INSTANT_MARKDOWN_BLOCK_EXTERNAL) {
69- csp += ' ; default-src "self"' ;
77+ csp.push(' default-src data: ' + CSP_SELF);
78+ csp.push(" style-src data: 'unsafe-inline' " + CSP_SELF);
79+ csp.push(' connect-src ' + CSP_SELF + ' ws://' + HTTP_HOST);
7080 }
7181 res.setHeader(' X-Content-Type-Options' , ' nosniff' );
72- res.setHeader(' Content-Security-Policy' , csp);
82+ res.setHeader(' Content-Security-Policy' , csp.join(' ; ' ));
83+ if (isIndexFile) {
84+ // Never cache the index file, to make sure that changes to the CSP are
85+ // picked up across soft reloads.
86+ res.setHeader(' Cache-Control' , ' no-store' );
87+ }
7388}
7489
7590function httpHandler(req, res) {
@@ -79,15 +94,16 @@ function httpHandler(req, res) {
7994 // Example: /my-repo/raw/master/sub-dir/some.png
8095 var githubUrl = req.url.match(/\/ [^\/ ]+\/ raw\/ [^\/ ]+\/ (.+)/);
8196 if (githubUrl) {
82- addSecurityHeaders(res, false);
97+ addSecurityHeaders(req, res, false);
8398 // Serve the file out of the current working directory
8499 send(req, githubUrl[1])
85100 .root(process.cwd ())
86101 .pipe(res);
87102 return ;
88103 }
89104
90- addSecurityHeaders(res, true);
105+ var isIndexFile = /^\/ (index\. html)? (\? | $)/.test(req.url);
106+ addSecurityHeaders(req, res, isIndexFile);
91107
92108 // Otherwise serve the file from the directory this module is in
93109 send(req, req.url)
0 commit comments