more tests on checkup page

pull/1/head
ansuz 3 years ago
parent e38e08fb6e
commit a54a0af604

@ -1,8 +1,8 @@
var Default = module.exports; var Default = module.exports;
Default.commonCSP = function (Env) { Default.commonCSP = function (Env) {
domain = ' ' + Env.httpUnsafeOrigin; var domain = ' ' + Env.httpUnsafeOrigin;
sandbox = Env.httpSafeOrigin; var sandbox = Env.httpSafeOrigin;
sandbox = (sandbox && sandbox !== domain? ' ' + sandbox: ''); sandbox = (sandbox && sandbox !== domain? ' ' + sandbox: '');
// Content-Security-Policy // Content-Security-Policy
@ -39,11 +39,11 @@ Default.commonCSP = function (Env) {
}; };
Default.contentSecurity = function (Env) { Default.contentSecurity = function (Env) {
return (Default.commonCSP(Env).join('; ') + "script-src 'self' resource: " + domain).replace(/\s+/g, ' '); return (Default.commonCSP(Env).join('; ') + "script-src 'self' resource: " + Env.httpUnsafeOrigin).replace(/\s+/g, ' ');
}; };
Default.padContentSecurity = function (Env) { Default.padContentSecurity = function (Env) {
return (Default.commonCSP(Env).join('; ') + "script-src 'self' 'unsafe-eval' 'unsafe-inline' resource: " + domain).replace(/\s+/g, ' '); return (Default.commonCSP(Env).join('; ') + "script-src 'self' 'unsafe-eval' 'unsafe-inline' resource: " + Env.httpUnsafeOrigin).replace(/\s+/g, ' ');
}; };
Default.httpHeaders = function (Env) { Default.httpHeaders = function (Env) {

@ -21,14 +21,42 @@ var isValidPort = function (p) {
return typeof(p) === 'number' && p < 65535; return typeof(p) === 'number' && p < 65535;
}; };
var deriveSandboxOrigin = function (unsafe, port) {
var url = new URL(unsafe);
url.port = port;
return url.origin;
};
module.exports.create = function (config) { module.exports.create = function (config) {
var httpUnsafeOrigin = canonicalizeOrigin(config.httpUnsafeOrigin);
var httpSafeOrigin;
var NO_SANDBOX = false;
var httpSafePort;
var httpPort = isValidPort(config.httpPort)? config.httpPort: 3000;
if (typeof(config.httpSafeOrigin) !== 'string') {
NO_SANDBOX = true;
if (typeof(config.httpSafePort) !== 'number') { httpSafePort = httpPort + 1; }
httpSafeOrigin = deriveSandboxOrigin(httpUnsafeOrigin, httpSafePort);
}
var permittedEmbedders = config.permittedEmbedders;
if (typeof(permittedEmbedders) === 'string') {
permittedEmbedders = permittedEmbedders.trim();
}
const Env = { const Env = {
fileHost: config.fileHost, // XXX
NO_SANDBOX: NO_SANDBOX,
httpSafePort: httpSafePort,
version: Package.version, version: Package.version,
installMethod: config.installMethod || undefined, installMethod: config.installMethod || undefined,
httpUnsafeOrigin: canonicalizeOrigin(config.httpUnsafeOrigin), httpUnsafeOrigin: httpUnsafeOrigin,
httpSafeOrigin: canonicalizeOrigin(config.httpSafeOrigin), httpSafeOrigin: httpSafeOrigin,
permittedEmbedders: typeof(config.permittedEmbedders) === 'string'? config.permittedEmbedders: canonicalizeOrigin(config.httpSafeOrigin), permittedEmbedders: typeof(permittedEmbedders) === 'string' && permittedEmbedders? permittedEmbedders: httpSafeOrigin,
removeDonateButton: config.removeDonateButton, removeDonateButton: config.removeDonateButton,
httpPort: isValidPort(config.httpPort)? config.httpPort: 3000, httpPort: isValidPort(config.httpPort)? config.httpPort: 3000,

@ -23,29 +23,17 @@ var fancyURL = function (domain, path) {
return false; return false;
}; };
var deriveSandboxOrigin = function (unsafe, port) {
var url = new URL(unsafe);
url.port = port;
return url.origin;
};
(function () { (function () {
// you absolutely must provide an 'httpUnsafeOrigin' (a truthy string) // you absolutely must provide an 'httpUnsafeOrigin' (a truthy string)
if (!Env.httpUnsafeOrigin || typeof(Env.httpUnsafeOrigin) !== 'string') { if (typeof(Env.httpUnsafeOrigin) !== 'string' || !Env.httpUnsafeOrigin.trim()) {
throw new Error("No 'httpUnsafeOrigin' provided"); throw new Error("No 'httpUnsafeOrigin' provided");
} }
if (typeof(Env.httpSafeOrigin) !== 'string') {
Env.NO_SANDBOX = true;
if (typeof(Env.httpSafePort) !== 'number') {
Env.httpSafePort = Env.httpPort + 1;
}
Env.httpSafeOrigin = deriveSandboxOrigin(Env.httpUnsafeOrigin, Env.httpSafePort);
}
}()); }());
var applyHeaderMap = function (res, map) { var applyHeaderMap = function (res, map) {
for (let header in map) { res.setHeader(header, map[header]); } for (let header in map) {
if (typeof(map[header]) === 'string') { res.setHeader(header, map[header]); }
}
}; };
var EXEMPT = [ var EXEMPT = [
@ -54,6 +42,11 @@ var EXEMPT = [
/^\/unsafeiframe\/inner\.html.*$/, /^\/unsafeiframe\/inner\.html.*$/,
]; ];
var cacheHeaders = function (Env, key, headers) {
if (Env.DEV_MODE) { return; }
Env[key] = headers;
};
var getHeaders = function (Env, type) { var getHeaders = function (Env, type) {
var key = type + 'HeadersCache'; var key = type + 'HeadersCache';
if (Env[key]) { return Env[key]; } if (Env[key]) { return Env[key]; }
@ -83,12 +76,12 @@ var getHeaders = function (Env, type) {
// because they aren't necessary and they cause problems // because they aren't necessary and they cause problems
// when duplicated by NGINX in production environments // when duplicated by NGINX in production environments
if (type === 'api') { if (type === 'api') {
Env[key] = headers; cacheHeaders(Env, key, headers);
return headers; return headers;
} }
headers["Cross-Origin-Resource-Policy"] = 'cross-origin'; headers["Cross-Origin-Resource-Policy"] = 'cross-origin';
Env[key] = headers; cacheHeaders(Env, key, headers);
return headers; return headers;
}; };
@ -103,6 +96,7 @@ var setHeaders = function (req, res) {
} }
var h = getHeaders(Env, type); var h = getHeaders(Env, type);
//console.log('PEWPEW', type, h);
applyHeaderMap(res, h); applyHeaderMap(res, h);
}; };
@ -140,7 +134,7 @@ app.use(function (req, res, next) {
if (req.method === 'OPTIONS' && /\/blob\//.test(req.url)) { if (req.method === 'OPTIONS' && /\/blob\//.test(req.url)) {
res.setHeader('Access-Control-Allow-Origin', Env.disableEmbedding? Env.permittedEmbedders: '*'); res.setHeader('Access-Control-Allow-Origin', Env.disableEmbedding? Env.permittedEmbedders: '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); 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-Allow-Headers', 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,Access-Control-Allow-Origin');
res.setHeader('Access-Control-Max-Age', 1728000); res.setHeader('Access-Control-Max-Age', 1728000);
res.setHeader('Content-Type', 'application/octet-stream; charset=utf-8'); res.setHeader('Content-Type', 'application/octet-stream; charset=utf-8');
res.setHeader('Content-Length', 0); res.setHeader('Content-Length', 0);
@ -241,6 +235,7 @@ var serveConfig = makeRouteCache(function (host) {
restrictRegistration: Env.restrictRegistration, restrictRegistration: Env.restrictRegistration,
httpSafeOrigin: Env.httpSafeOrigin, httpSafeOrigin: Env.httpSafeOrigin,
disableEmbedding: Env.disableEmbedding, disableEmbedding: Env.disableEmbedding,
fileHost: Env.fileHost,
}, null, '\t'), }, null, '\t'),
'});' '});'
].join(';\n') ].join(';\n')

@ -1045,7 +1045,10 @@ define([
code(header), code(header),
' should only match trusted domains.', ' should only match trusted domains.',
])); ]));
return void cb(raw); return void cb({
header: raw,
expected: trimmedSafe,
});
} }
} }
@ -1271,6 +1274,41 @@ define([
}); });
}); });
assert(function (cb, msg) {
var url;
try {
url = new URL('/', trimmedUnsafe);
} catch (err) {
return void cb({
error: err,
});
}
// XXX don't bother checking cors headers in dev environment
if (url.protocol !== 'https') { return void cb(true); } // XXX
var header = 'Access-Control-Allow-Origin';
msg.appendChild(h('span', [
'pewpew ',
code(header), // XXX
]));
deferredPostMessage({
command: 'GET_HEADER',
content: {
url: url.href,
header: header,
},
}, function (raw) {
if (raw === '*') { return void cb(true); }
if (raw === trimmedSafe) { return void cb(true); }
cb({
response: raw,
disableEmbedding: ApiConfig.disableEmbedding,
});
});
});
var serverToken; var serverToken;
Tools.common_xhr('/', function (xhr) { Tools.common_xhr('/', function (xhr) {
serverToken = xhr.getResponseHeader('server'); serverToken = xhr.getResponseHeader('server');

Loading…
Cancel
Save