stricter websocket CSP and tests to match

pull/1/head
ansuz 3 years ago
parent c0686dad99
commit 7b6c8b83ef

@ -24,7 +24,7 @@ Default.commonCSP = function (domain, sandbox) {
if you are deploying to production, you'll probably want to remove if you are deploying to production, you'll probably want to remove
the ws://* directive the ws://* directive
*/ */
"connect-src 'self' ws: blob: " + domain + sandbox, "connect-src 'self' blob: " + (/^https:/.test(domain)? 'wss:': domain.replace('http://', 'ws://')) + ' ' + domain + sandbox,
// data: is used by codemirror // data: is used by codemirror
"img-src 'self' data: blob:" + domain, "img-src 'self' data: blob:" + domain,

@ -14,13 +14,14 @@ define([
'/common/outer/network-config.js', '/common/outer/network-config.js',
'/customize/pages.js', '/customize/pages.js',
'/checkup/checkup-tools.js', '/checkup/checkup-tools.js',
'/common/outer/network-config.js',
'/bower_components/tweetnacl/nacl-fast.min.js', '/bower_components/tweetnacl/nacl-fast.min.js',
'css!/bower_components/components-font-awesome/css/font-awesome.min.css', 'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
'less!/checkup/app-checkup.less', 'less!/checkup/app-checkup.less',
], function ($, ApiConfig, Assertions, h, Messages, DomReady, ], function ($, ApiConfig, Assertions, h, Messages, DomReady,
nThen, SFCommonO, Login, Hash, Util, Pinpad, nThen, SFCommonO, Login, Hash, Util, Pinpad,
NetConfig, Pages, Tools) { NetConfig, Pages, Tools, NetConfig) {
var Assert = Assertions(); var Assert = Assertions();
var trimSlashes = function (s) { var trimSlashes = function (s) {
if (typeof(s) !== 'string') { return s; } if (typeof(s) !== 'string') { return s; }
@ -71,6 +72,14 @@ define([
var trimmedSafe = trimSlashes(ApiConfig.httpSafeOrigin); var trimmedSafe = trimSlashes(ApiConfig.httpSafeOrigin);
var trimmedUnsafe = trimSlashes(ApiConfig.httpUnsafeOrigin); var trimmedUnsafe = trimSlashes(ApiConfig.httpUnsafeOrigin);
var fileHost = ApiConfig.fileHost;
var API_URL;
try {
API_URL = new URL(NetConfig.getWebsocketURL(window.location.origin), trimmedUnsafe);
} catch (err) {
console.error(err);
};
assert(function (cb, msg) { assert(function (cb, msg) {
msg.appendChild(h('span', [ msg.appendChild(h('span', [
@ -843,6 +852,36 @@ define([
}); });
}); });
assert(function (cb, msg) {
msg.appendChild(h('span', [
"An invalid ",
code("fileHost"),
" value was provided by ",
code('/api/config'),
'.',
]));
// it's OK not to provide a 'fileHost' value
if (typeof(fileHost) === 'undefined') { return void cb(true); }
// if one is provided, we expect it to be HTTPS
if (!isHTTPS(fileHost)) { return void cb(fileHost); }
// Otherwise I guess it's OK?
cb(true);
});
assert(function (cb, msg) {
msg.appendChild(h('span', [
'This instance is configured to use an invalid websocket URL.',
]));
if (!API_URL) { return void cb('INVALID_WEBSOCKET'); }
if (isHTTPS(trimmedUnsafe) && API_URL.protocol !== 'wss:') {
return void cb("PROTOCOL_MISMATCH");
}
return void cb(true);
});
/* /*
assert(function (cb, msg) { assert(function (cb, msg) {
msg.appendChild(h('span', [ msg.appendChild(h('span', [
@ -929,9 +968,8 @@ define([
'blob:', 'blob:',
$outer, $outer,
$sandbox, $sandbox,
/https:\/\//.test($outer)? $outer.replace('https://', 'wss://') : 'ws:', API_URL.origin,
// XXX https://$files_domain isHTTPS(fileHost)? fileHost: undefined,
// XXX wss://$api_domain
], ],
'img-src': ["'self'", 'data:', 'blob:', $outer], 'img-src': ["'self'", 'data:', 'blob:', $outer],
@ -967,9 +1005,8 @@ define([
'blob:', 'blob:',
$outer, $outer,
$sandbox, $sandbox,
/https:\/\//.test($outer)? $outer.replace('https://', 'wss://') : 'ws:', API_URL.origin,
// XXX https://$files_domain isHTTPS(fileHost)? fileHost: undefined,
// XXX wss://$api_domain
], ],
'img-src': ["'self'", 'data:', 'blob:', $outer], 'img-src': ["'self'", 'data:', 'blob:', $outer],
'media-src': ['blob:'], 'media-src': ['blob:'],

@ -11,7 +11,7 @@ define([
window.parent.postMessage(JSON.stringify(content), '*'); window.parent.postMessage(JSON.stringify(content), '*');
}; };
postMessage({ command: "READY", }); postMessage({ command: "READY", });
var getHeaders = function (url, cb) { // XXX reuse XHR objects? var getHeaders = function (url, cb) {
Tools.common_xhr(url, function (xhr) { Tools.common_xhr(url, function (xhr) {
var allHeaders = xhr.getAllResponseHeaders(); var allHeaders = xhr.getAllResponseHeaders();
return void cb(void 0, allHeaders, xhr); return void cb(void 0, allHeaders, xhr);

Loading…
Cancel
Save