|
|
@ -369,7 +369,6 @@ define([
|
|
|
|
var expect = {
|
|
|
|
var expect = {
|
|
|
|
'cross-origin-resource-policy': 'cross-origin',
|
|
|
|
'cross-origin-resource-policy': 'cross-origin',
|
|
|
|
'cross-origin-embedder-policy': 'require-corp',
|
|
|
|
'cross-origin-embedder-policy': 'require-corp',
|
|
|
|
//'cross-origin-opener-policy': 'same-origin', // FIXME this is in our nginx config but not server.js
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
$.ajax(url, {
|
|
|
|
$.ajax(url, {
|
|
|
@ -654,7 +653,7 @@ define([
|
|
|
|
]);
|
|
|
|
]);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
assert(function (_cb, msg) {
|
|
|
|
assert(function (_cb, msg) { // FIXME possibly superseded by more advanced CSP tests?
|
|
|
|
var url = '/sheet/inner.html';
|
|
|
|
var url = '/sheet/inner.html';
|
|
|
|
var cb = Util.once(Util.mkAsync(_cb));
|
|
|
|
var cb = Util.once(Util.mkAsync(_cb));
|
|
|
|
msg.appendChild(CSP_WARNING(url));
|
|
|
|
msg.appendChild(CSP_WARNING(url));
|
|
|
@ -670,7 +669,7 @@ define([
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
assert(function (cb, msg) {
|
|
|
|
assert(function (cb, msg) { // FIXME possibly superseded by more advanced CSP tests?
|
|
|
|
var url = '/common/onlyoffice/v5/web-apps/apps/spreadsheeteditor/main/index.html';
|
|
|
|
var url = '/common/onlyoffice/v5/web-apps/apps/spreadsheeteditor/main/index.html';
|
|
|
|
msg.appendChild(CSP_WARNING(url));
|
|
|
|
msg.appendChild(CSP_WARNING(url));
|
|
|
|
deferredPostMessage({
|
|
|
|
deferredPostMessage({
|
|
|
@ -803,36 +802,7 @@ define([
|
|
|
|
cb(isHTTPS(trimmedUnsafe) && isHTTPS(trimmedSafe));
|
|
|
|
cb(isHTTPS(trimmedUnsafe) && isHTTPS(trimmedSafe));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
[
|
|
|
|
assert(function (cb, msg) { // FIXME this test has been superceded, but the descriptive text is still useful
|
|
|
|
//'sheet',
|
|
|
|
|
|
|
|
//'presentation',
|
|
|
|
|
|
|
|
//'doc',
|
|
|
|
|
|
|
|
//'convert',
|
|
|
|
|
|
|
|
].forEach(function (url) {
|
|
|
|
|
|
|
|
assert(function (cb, msg) {
|
|
|
|
|
|
|
|
var header = 'cross-origin-opener-policy';
|
|
|
|
|
|
|
|
var expected = 'same-origin';
|
|
|
|
|
|
|
|
deferredPostMessage({
|
|
|
|
|
|
|
|
command: 'GET_HEADER',
|
|
|
|
|
|
|
|
content: {
|
|
|
|
|
|
|
|
url: '/' + url + '/',
|
|
|
|
|
|
|
|
header: header,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}, function (content) {
|
|
|
|
|
|
|
|
msg.appendChild(h('span', [
|
|
|
|
|
|
|
|
code(url),
|
|
|
|
|
|
|
|
' was served without the correct ',
|
|
|
|
|
|
|
|
code(header),
|
|
|
|
|
|
|
|
' HTTP header value (',
|
|
|
|
|
|
|
|
code(expected),
|
|
|
|
|
|
|
|
'). This will interfere with your ability to convert between office file formats.'
|
|
|
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
cb(content === expected);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert(function (cb, msg) { // XXX this test has been superceded
|
|
|
|
|
|
|
|
// check that the sandbox domain is included in connect-src
|
|
|
|
// check that the sandbox domain is included in connect-src
|
|
|
|
msg.appendChild(h('span', [
|
|
|
|
msg.appendChild(h('span', [
|
|
|
|
"This instance's ",
|
|
|
|
"This instance's ",
|
|
|
@ -856,42 +826,8 @@ define([
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
assert(function (cb, msg) { // XXX this test has been superceded
|
|
|
|
|
|
|
|
var directives = [
|
|
|
|
|
|
|
|
'img-src',
|
|
|
|
|
|
|
|
'media-src',
|
|
|
|
|
|
|
|
'child-src',
|
|
|
|
|
|
|
|
'frame-src'
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
msg.appendChild(h('span', [
|
|
|
|
|
|
|
|
"This instance's ",
|
|
|
|
|
|
|
|
code("Content-Security-Policy"),
|
|
|
|
|
|
|
|
" headers are unnecessarily permissive.",
|
|
|
|
|
|
|
|
h('br'),
|
|
|
|
|
|
|
|
h('br'),
|
|
|
|
|
|
|
|
" Review the recommended settings for ",
|
|
|
|
|
|
|
|
code('img-src'), ', ',
|
|
|
|
|
|
|
|
code('media-src'), ', ',
|
|
|
|
|
|
|
|
code('child-src'), ', and ',
|
|
|
|
|
|
|
|
code('frame-src'),
|
|
|
|
|
|
|
|
" in the provided NGINX configuration file for an example of how to set these headers correctly.",
|
|
|
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
Tools.common_xhr('/', function (xhr) {
|
|
|
|
|
|
|
|
var CSP = parseCSP(xhr.getResponseHeader('content-security-policy'));
|
|
|
|
|
|
|
|
// check that the relevant CSP directives are defined
|
|
|
|
|
|
|
|
// and that none of them permit general remote content via '*'
|
|
|
|
|
|
|
|
if (directives.every(function (k) {
|
|
|
|
|
|
|
|
return typeof(CSP[k]) === 'string' && !/ \* /.test(CSP[k]);
|
|
|
|
|
|
|
|
})) {
|
|
|
|
|
|
|
|
return void cb(true);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
cb(CSP);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert(function (cb, msg) {
|
|
|
|
assert(function (cb, msg) {
|
|
|
|
msg.appendChild(h('span', [ // XXX
|
|
|
|
msg.appendChild(h('span', [
|
|
|
|
code('/api/config'),
|
|
|
|
code('/api/config'),
|
|
|
|
" returned an HTTP status code other than ",
|
|
|
|
" returned an HTTP status code other than ",
|
|
|
|
code('200'),
|
|
|
|
code('200'),
|
|
|
@ -985,8 +921,8 @@ define([
|
|
|
|
'child-src': [$outer], //["'self'", 'blob:', $outer, $sandbox],
|
|
|
|
'child-src': [$outer], //["'self'", 'blob:', $outer, $sandbox],
|
|
|
|
'frame-src': ["'self'", 'blob:', /*$outer, */$sandbox],
|
|
|
|
'frame-src': ["'self'", 'blob:', /*$outer, */$sandbox],
|
|
|
|
'script-src': ["'self'", 'resource:', $outer,
|
|
|
|
'script-src': ["'self'", 'resource:', $outer,
|
|
|
|
"'unsafe-eval'", // XXX sloppy onlyoffice BS
|
|
|
|
"'unsafe-eval'",
|
|
|
|
"'unsafe-inline'", // XXX sloppy onlyoffice BS
|
|
|
|
"'unsafe-inline'",
|
|
|
|
],
|
|
|
|
],
|
|
|
|
'connect-src': [
|
|
|
|
'connect-src': [
|
|
|
|
"'self'",
|
|
|
|
"'self'",
|
|
|
@ -994,7 +930,6 @@ define([
|
|
|
|
$outer,
|
|
|
|
$outer,
|
|
|
|
$sandbox,
|
|
|
|
$sandbox,
|
|
|
|
/https:\/\//.test($outer)? $outer.replace('https://', 'wss://') : 'ws:',
|
|
|
|
/https:\/\//.test($outer)? $outer.replace('https://', 'wss://') : 'ws:',
|
|
|
|
///https:/.test($outer)? '': 'ws:', // XXX warn about ws: unless the origin is unencrypted
|
|
|
|
|
|
|
|
],
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
|
|
'img-src': ["'self'", 'data:', 'blob:', $outer],
|
|
|
|
'img-src': ["'self'", 'data:', 'blob:', $outer],
|
|
|
@ -1031,8 +966,6 @@ define([
|
|
|
|
$outer,
|
|
|
|
$outer,
|
|
|
|
$sandbox,
|
|
|
|
$sandbox,
|
|
|
|
/https:\/\//.test($outer)? $outer.replace('https://', 'wss://') : 'ws:',
|
|
|
|
/https:\/\//.test($outer)? $outer.replace('https://', 'wss://') : 'ws:',
|
|
|
|
///https:/.test($outer)? '': 'ws:', // XXX warn about ws: unless the origin is unencrypted
|
|
|
|
|
|
|
|
//'wss:', // XXX always accept wss: ???
|
|
|
|
|
|
|
|
],
|
|
|
|
],
|
|
|
|
'img-src': ["'self'", 'data:', 'blob:', $outer],
|
|
|
|
'img-src': ["'self'", 'data:', 'blob:', $outer],
|
|
|
|
'media-src': ['blob:'],
|
|
|
|
'media-src': ['blob:'],
|
|
|
@ -1045,46 +978,62 @@ define([
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
assert(function (cb, msg) {
|
|
|
|
assert(function (cb, msg) {
|
|
|
|
var header = 'access-control-allow-origin';
|
|
|
|
var header = 'Access-Control-Allow-Origin';
|
|
|
|
msg.appendChild(h('span', [
|
|
|
|
msg.appendChild(h('span', [
|
|
|
|
header,
|
|
|
|
'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) {
|
|
|
|
Tools.common_xhr('/', function (xhr) {
|
|
|
|
var raw = xhr.getResponseHeader(header);
|
|
|
|
var raw = xhr.getResponseHeader(header);
|
|
|
|
cb(raw === "*" || raw); // XXX
|
|
|
|
cb(raw === "*" || raw);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
assert(function (cb, msg) {
|
|
|
|
assert(function (cb, msg) {
|
|
|
|
var header = 'cross-origin-embedder-policy';
|
|
|
|
var header = 'Cross-Origin-Embedder-Policy';
|
|
|
|
msg.appendChild(h('span', [
|
|
|
|
msg.appendChild(h('span', [
|
|
|
|
header,
|
|
|
|
"Assets must be served with a ",
|
|
|
|
|
|
|
|
code(header),
|
|
|
|
|
|
|
|
' value of ',
|
|
|
|
|
|
|
|
code('require-corp'),
|
|
|
|
|
|
|
|
" to enable browser features required for client-side document conversion.",
|
|
|
|
]));
|
|
|
|
]));
|
|
|
|
Tools.common_xhr('/', function (xhr) {
|
|
|
|
Tools.common_xhr('/', function (xhr) {
|
|
|
|
var raw = xhr.getResponseHeader(header);
|
|
|
|
var raw = xhr.getResponseHeader(header);
|
|
|
|
cb(raw === 'require-corp' || raw); // XXX
|
|
|
|
cb(raw === 'require-corp' || raw);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
assert(function (cb, msg) {
|
|
|
|
assert(function (cb, msg) {
|
|
|
|
var header = 'cross-origin-resource-policy';
|
|
|
|
var header = 'Cross-Origin-Resource-Policy';
|
|
|
|
msg.appendChild(h('span', [
|
|
|
|
msg.appendChild(h('span', [
|
|
|
|
header,
|
|
|
|
"Assets must be served with a ",
|
|
|
|
|
|
|
|
code(header),
|
|
|
|
|
|
|
|
' value of ',
|
|
|
|
|
|
|
|
code('cross-origin'),
|
|
|
|
|
|
|
|
" to enable browser features required for client-side document conversion.",
|
|
|
|
]));
|
|
|
|
]));
|
|
|
|
Tools.common_xhr('/', function (xhr) {
|
|
|
|
Tools.common_xhr('/', function (xhr) {
|
|
|
|
var raw = xhr.getResponseHeader(header);
|
|
|
|
var raw = xhr.getResponseHeader(header);
|
|
|
|
cb(raw === 'cross-origin' || raw); // XXX
|
|
|
|
cb(raw === 'cross-origin' || raw);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
assert(function (cb, msg) {
|
|
|
|
assert(function (cb, msg) {
|
|
|
|
var header = 'X-Content-Type-Options';
|
|
|
|
var header = 'X-Content-Type-Options';
|
|
|
|
msg.appendChild(h('span', [
|
|
|
|
msg.appendChild(h('span', [
|
|
|
|
header,
|
|
|
|
"Assets should be served with an ",
|
|
|
|
|
|
|
|
code(header),
|
|
|
|
|
|
|
|
' header with a value of ',
|
|
|
|
|
|
|
|
code('nosniff'),
|
|
|
|
|
|
|
|
'.',
|
|
|
|
]));
|
|
|
|
]));
|
|
|
|
Tools.common_xhr('/', function (xhr) {
|
|
|
|
Tools.common_xhr('/', function (xhr) {
|
|
|
|
var raw = xhr.getResponseHeader(header);
|
|
|
|
var raw = xhr.getResponseHeader(header);
|
|
|
|
cb(raw === 'nosniff' || raw); // XXX
|
|
|
|
cb(raw === 'nosniff' || raw);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
@ -1100,7 +1049,7 @@ define([
|
|
|
|
// Cache-Control should be 'no-cache' unless the URL includes ver=
|
|
|
|
// Cache-Control should be 'no-cache' unless the URL includes ver=
|
|
|
|
Tools.common_xhr('/', function (xhr) {
|
|
|
|
Tools.common_xhr('/', function (xhr) {
|
|
|
|
var raw = xhr.getResponseHeader(header);
|
|
|
|
var raw = xhr.getResponseHeader(header);
|
|
|
|
cb(raw === 'no-cache' || raw); // XXX
|
|
|
|
cb(raw === 'no-cache' || raw);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
@ -1114,7 +1063,7 @@ define([
|
|
|
|
// Cache-Control should be 'max-age=<number>' if the URL includes 'ver='
|
|
|
|
// Cache-Control should be 'max-age=<number>' if the URL includes 'ver='
|
|
|
|
Tools.common_xhr('/customize/messages.js?ver=' +(+new Date()), function (xhr) {
|
|
|
|
Tools.common_xhr('/customize/messages.js?ver=' +(+new Date()), function (xhr) {
|
|
|
|
var raw = xhr.getResponseHeader(header);
|
|
|
|
var raw = xhr.getResponseHeader(header);
|
|
|
|
cb(/max\-age=\d+$/.test(raw) || raw); // XXX
|
|
|
|
cb(/max\-age=\d+$/.test(raw) || raw);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
@ -1167,13 +1116,6 @@ define([
|
|
|
|
});
|
|
|
|
});
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
if (false) {
|
|
|
|
|
|
|
|
assert(function (cb, msg) {
|
|
|
|
|
|
|
|
msg.innerText = 'fake test to simulate failure';
|
|
|
|
|
|
|
|
cb(false);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var row = function (cells) {
|
|
|
|
var row = function (cells) {
|
|
|
|
return h('tr', cells.map(function (cell) {
|
|
|
|
return h('tr', cells.map(function (cell) {
|
|
|
|
return h('td', cell);
|
|
|
|
return h('td', cell);
|
|
|
|