more tests on checkup page
parent
e38e08fb6e
commit
a54a0af604
|
@ -1,8 +1,8 @@
|
|||
var Default = module.exports;
|
||||
|
||||
Default.commonCSP = function (Env) {
|
||||
domain = ' ' + Env.httpUnsafeOrigin;
|
||||
sandbox = Env.httpSafeOrigin;
|
||||
var domain = ' ' + Env.httpUnsafeOrigin;
|
||||
var sandbox = Env.httpSafeOrigin;
|
||||
sandbox = (sandbox && sandbox !== domain? ' ' + sandbox: '');
|
||||
// Content-Security-Policy
|
||||
|
||||
|
@ -39,11 +39,11 @@ Default.commonCSP = 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) {
|
||||
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) {
|
||||
|
|
34
lib/env.js
34
lib/env.js
|
@ -21,14 +21,42 @@ var isValidPort = function (p) {
|
|||
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) {
|
||||
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 = {
|
||||
fileHost: config.fileHost, // XXX
|
||||
NO_SANDBOX: NO_SANDBOX,
|
||||
httpSafePort: httpSafePort,
|
||||
|
||||
version: Package.version,
|
||||
installMethod: config.installMethod || undefined,
|
||||
|
||||
httpUnsafeOrigin: canonicalizeOrigin(config.httpUnsafeOrigin),
|
||||
httpSafeOrigin: canonicalizeOrigin(config.httpSafeOrigin),
|
||||
permittedEmbedders: typeof(config.permittedEmbedders) === 'string'? config.permittedEmbedders: canonicalizeOrigin(config.httpSafeOrigin),
|
||||
httpUnsafeOrigin: httpUnsafeOrigin,
|
||||
httpSafeOrigin: httpSafeOrigin,
|
||||
permittedEmbedders: typeof(permittedEmbedders) === 'string' && permittedEmbedders? permittedEmbedders: httpSafeOrigin,
|
||||
|
||||
removeDonateButton: config.removeDonateButton,
|
||||
httpPort: isValidPort(config.httpPort)? config.httpPort: 3000,
|
||||
|
|
33
server.js
33
server.js
|
@ -23,29 +23,17 @@ var fancyURL = function (domain, path) {
|
|||
return false;
|
||||
};
|
||||
|
||||
var deriveSandboxOrigin = function (unsafe, port) {
|
||||
var url = new URL(unsafe);
|
||||
url.port = port;
|
||||
return url.origin;
|
||||
};
|
||||
|
||||
(function () {
|
||||
// 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");
|
||||
}
|
||||
|
||||
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) {
|
||||
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 = [
|
||||
|
@ -54,6 +42,11 @@ var EXEMPT = [
|
|||
/^\/unsafeiframe\/inner\.html.*$/,
|
||||
];
|
||||
|
||||
var cacheHeaders = function (Env, key, headers) {
|
||||
if (Env.DEV_MODE) { return; }
|
||||
Env[key] = headers;
|
||||
};
|
||||
|
||||
var getHeaders = function (Env, type) {
|
||||
var key = type + 'HeadersCache';
|
||||
if (Env[key]) { return Env[key]; }
|
||||
|
@ -83,12 +76,12 @@ var getHeaders = function (Env, type) {
|
|||
// because they aren't necessary and they cause problems
|
||||
// when duplicated by NGINX in production environments
|
||||
if (type === 'api') {
|
||||
Env[key] = headers;
|
||||
cacheHeaders(Env, key, headers);
|
||||
return headers;
|
||||
}
|
||||
|
||||
headers["Cross-Origin-Resource-Policy"] = 'cross-origin';
|
||||
Env[key] = headers;
|
||||
cacheHeaders(Env, key, headers);
|
||||
return headers;
|
||||
};
|
||||
|
||||
|
@ -103,6 +96,7 @@ var setHeaders = function (req, res) {
|
|||
}
|
||||
|
||||
var h = getHeaders(Env, type);
|
||||
//console.log('PEWPEW', type, h);
|
||||
applyHeaderMap(res, h);
|
||||
};
|
||||
|
||||
|
@ -140,7 +134,7 @@ app.use(function (req, res, next) {
|
|||
if (req.method === 'OPTIONS' && /\/blob\//.test(req.url)) {
|
||||
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-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('Content-Type', 'application/octet-stream; charset=utf-8');
|
||||
res.setHeader('Content-Length', 0);
|
||||
|
@ -241,6 +235,7 @@ var serveConfig = makeRouteCache(function (host) {
|
|||
restrictRegistration: Env.restrictRegistration,
|
||||
httpSafeOrigin: Env.httpSafeOrigin,
|
||||
disableEmbedding: Env.disableEmbedding,
|
||||
fileHost: Env.fileHost,
|
||||
}, null, '\t'),
|
||||
'});'
|
||||
].join(';\n')
|
||||
|
|
|
@ -1045,7 +1045,10 @@ define([
|
|||
code(header),
|
||||
' 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;
|
||||
Tools.common_xhr('/', function (xhr) {
|
||||
serverToken = xhr.getResponseHeader('server');
|
||||
|
|
Loading…
Reference in New Issue