From 0917b45035b2a511f58a578785f1edbc70d6a59a Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 18 Feb 2022 16:09:02 +0530 Subject: [PATCH] implement proper support for forbidding remote media-tag inclusion ...and test that the basic headers are correctly set on the checkup page --- lib/defaults.js | 2 +- lib/env.js | 3 ++- server.js | 4 ++-- www/checkup/main.js | 26 +++++++++++++++++--------- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/lib/defaults.js b/lib/defaults.js index 85d3be55e..44cfef5f0 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -50,7 +50,7 @@ Default.httpHeaders = function (Env) { return { "X-XSS-Protection": "1; mode=block", "X-Content-Type-Options": "nosniff", - "Access-Control-Allow-Origin": Env.disableEmbedding? '': "*", + "Access-Control-Allow-Origin": Env.disableEmbedding? Env.permittedEmbedders: "*", "Permissions-policy":"interest-cohort=()" }; }; diff --git a/lib/env.js b/lib/env.js index fe2fa4828..f92eae98c 100644 --- a/lib/env.js +++ b/lib/env.js @@ -28,6 +28,8 @@ module.exports.create = function (config) { httpUnsafeOrigin: canonicalizeOrigin(config.httpUnsafeOrigin), httpSafeOrigin: canonicalizeOrigin(config.httpSafeOrigin), + permittedEmbedders: typeof(config.permittedEmbedders) === 'string'? config.permittedEmbedders: canonicalizeOrigin(config.httpSafeOrigin), + removeDonateButton: config.removeDonateButton, httpPort: isValidPort(config.httpPort)? config.httpPort: 3000, httpAddress: typeof(config.httpAddress) === 'string'? config.httpAddress: '127.0.0.1', @@ -68,7 +70,6 @@ module.exports.create = function (config) { archiveRetentionTime: config.archiveRetentionTime, accountRetentionTime: config.accountRetentionTime, - // TODO implement mutability adminEmail: config.adminEmail, supportMailbox: config.supportMailboxPublicKey, diff --git a/server.js b/server.js index a08a7e5c3..498b7465b 100644 --- a/server.js +++ b/server.js @@ -126,7 +126,7 @@ app.use('/blob', function (req, res, next) { if (req.method === 'HEAD') { Express.static(Path.join(__dirname, Env.paths.blob), { setHeaders: function (res, path, stat) { - res.set('Access-Control-Allow-Origin', '*'); + res.set('Access-Control-Allow-Origin', Env.disableEmbedding? Env.permittedEmbedders: '*'); res.set('Access-Control-Allow-Headers', 'Content-Length'); res.set('Access-Control-Expose-Headers', 'Content-Length'); } @@ -138,7 +138,7 @@ app.use('/blob', function (req, res, next) { app.use(function (req, res, next) { if (req.method === 'OPTIONS' && /\/blob\//.test(req.url)) { - res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Origin', Env.disableEmbedding? Env.permittedEmbedders: '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'); res.setHeader('Access-Control-Max-Age', 1728000); diff --git a/www/checkup/main.js b/www/checkup/main.js index f465283cc..c858e6281 100644 --- a/www/checkup/main.js +++ b/www/checkup/main.js @@ -1026,23 +1026,31 @@ define([ assert(function (cb, msg) { var header = 'Access-Control-Allow-Origin'; - msg.appendChild(h('span', [ // XXX update text to indicate that the value doesn't match their preference - 'Assets must be served with an ', - code(header), - ' header with a value of ', - code("'*'"), - ' if you wish to support embedding of encrypted media on third party websites.', - ])); Tools.common_xhr('/', function (xhr) { var raw = xhr.getResponseHeader(header); if (ApiConfig.disableEmbedding) { - if ([null, ''].includes(raw)) { return void cb(true); } + if (raw === trimmedSafe) { return void cb(true); } else { - return void cb(raw === '*' || raw); + msg.appendChild(h('span', [ + 'This instance has been configured to disable support for embedding assets in third-party websites. ', + 'In order for this setting to be effective while still permitting encrypted media to load locally ', + 'the ', + code(header), + ' should only match trusted domains.', + ])); + return void cb(raw); } } + msg.appendChild(h('span', [ + 'Assets must be served with an ', + code(header), + ' header with a value of ', + code("'*'"), + ' if you wish to support embedding of encrypted media on third party websites.', + ])); + cb(raw === "*" || raw); }); });