openvibers/openvibe.bench Commits

Showcase: the wrapper keeps the render origin (#22)

OP OpenVibers committed 14 days ago · 67f13f1a89 · 3 files, +8 −2

frame-ancestors checks every ancestor. The showcase framed the wrapper with
sandbox=allow-scripts, so the wrapper had an opaque origin and the model
document's frame-ancestors matched none of its ancestors. The wrapper is our
code on the cookie-less render origin: its frame now has allow-same-origin.
The model output keeps sandbox=allow-scripts (opaque) one level down.

Changes

ddiff --git a/server/bench/render.js b/server/bench/render.js
iindex ac44d88..c2f1a0f 100644
---- a/server/bench/render.js
++++ b/server/bench/render.js
@@@ -37,6 +37,10 @@ function wrapperCsp(nonce) {
const metaPolicy = (p) => p.split('; ').filter((d) => !d.startsWith('frame-ancestors')).join('; ');
/** The sandbox attributes for every model frame: scripts yes, everything else no. */
const SANDBOX = 'allow-scripts';
++/** The wrapper's own frame on the showcase pages. The wrapper is our code on the cookie-less render origin, and it keeps
++ * that origin: frame-ancestors on the model document checks every ancestor, and a wrapper with an opaque origin matched
++ * none, so Chrome refused every model frame. The model output stays in SANDBOX (opaque) one level down. */
++const WRAPPER_SANDBOX = 'allow-scripts allow-same-origin';
/** The default wall-clock a kind may run before the wrapper stops it. */
const DEFAULT_LIMIT_MS = 20000;
/** The hard size cap on one entry, the same cap sanitizeHtml already applies. */
@@@ -210,6 +214,6 @@ function wrapperDocument(opts) {
}
module.exports = {
-- RENDER_ORIGIN, PINNED_ORIGINS, VENDOR, SANDBOX, DEFAULT_LIMIT_MS, MAX_ENTRY_BYTES,
++ RENDER_ORIGIN, PINNED_ORIGINS, VENDOR, SANDBOX, WRAPPER_SANDBOX, DEFAULT_LIMIT_MS, MAX_ENTRY_BYTES,
FRAME_ANCESTORS, wrapperCsp, cspFor, applyNonce, sanitizeSvg, limitMsOf, modeOf, modelDocument, wrapperDocument,
};
ddiff --git a/server/http/showcase.js b/server/http/showcase.js
iindex 528a5c6..ceb648e 100644
---- a/server/http/showcase.js
++++ b/server/http/showcase.js
@@@ -142,7 +142,7 @@ async function loadStats(ctx) {
function pane(slot, revealed) {
const frame = '<iframe class="sc-pane-frame" src="' + esc(slot.wrapper_url) + '" title="Output ' + esc(slot.slot) + '"'
-- + ' sandbox="' + esc(renderLib.SANDBOX) + '" referrerpolicy="no-referrer" loading="lazy" data-entry-id="' + esc(slot.entry_id) + '"></iframe>';
++ + ' sandbox="' + esc(renderLib.WRAPPER_SANDBOX) + '" referrerpolicy="no-referrer" loading="lazy" data-entry-id="' + esc(slot.entry_id) + '"></iframe>';
const facts = revealed
? '<dl class="sc-pane-facts" data-facts="' + esc(slot.slot) + '">'
+ '<div><dt>Model</dt><dd>' + esc(slot.model) + '</dd></div>'
ddiff --git a/test/showcase.test.js b/test/showcase.test.js
iindex 1e322f7..c79ef8c 100644
---- a/test/showcase.test.js
++++ b/test/showcase.test.js
@@@ -150,6 +150,8 @@ const HOSTILE = [
assert.strictEqual(pair.slots[0].slot, 'A');
assert.strictEqual(pair.slots[1].slot, 'B');
assert.strictEqual(pair.slots[0].model, undefined, 'no model before the vote');
++ assert.strictEqual(renderLib.WRAPPER_SANDBOX, 'allow-scripts allow-same-origin', 'the wrapper keeps the render origin, so the model frame\'s frame-ancestors match');
++ assert.ok(!renderLib.SANDBOX.includes('allow-same-origin'), 'the model output never keeps an origin');
assert.ok(pair.slots[0].wrapper_url.startsWith(renderLib.RENDER_ORIGIN + '/render/w/'), 'the wrapper is on the render origin: ' + pair.slots[0].wrapper_url);
});