openvibers/openvibe.network Commits

SSRF test: the card fetcher may reach exactly the open sites' hosts (#635)

OP OpenVibers committed 6 days ago · 8aeda8976d · 1 file, +6 −3

Changes

ddiff --git a/test/security-ssrf.test.js b/test/security-ssrf.test.js
iindex c6fffa82..8cd50118 100644
---- a/test/security-ssrf.test.js
++++ b/test/security-ssrf.test.js
@@@ -281,9 +281,12 @@ function inventory(root) {
assert.strictEqual(target.count(), 0, 'nothing connected to the address a person named');
assert.deepStrictEqual(made.filter((c) => c.endsWith(` ${T}`)), [], 'no connection to the chosen port at all');
const hosts = new Set(made.map((c) => c.split(' ')[0]));
-- // openvibe.* is the menu-cards fetcher: every open site's fixed https://<site host>/.well-known/openvibe-menu.json
-- // (server/frame/menu-cards.js, reviewed above). It reads first-party hosts only, never a value a person named.
-- for (const h of hosts) assert.ok(['127.0.0.1', 'discord.com', 'gateway.discord.gg', 'api.github.com'].includes(h) || h.startsWith('openvibe.'), `unexpected destination ${h}`);
++ // The menu-cards fetcher (server/frame/menu-cards.js, reviewed above) reads every open site's fixed
++ // https://<site host>/.well-known/openvibe-menu.json on a five-minute timer, so whether it runs during this test
++ // is timing. The hosts it may reach are exactly the open sites' hosts in server/frame/sites.js (openvibe.live,
++ // openre.stream, ...), never a value a person named; anything else, a look-alike included, is unexpected.
++ const SITE_HOSTS = new Set(require('../server/frame/sites').SITES.filter((s) => s.status === 'open').map((s) => s.host));
++ for (const h of hosts) assert.ok(['127.0.0.1', 'discord.com', 'gateway.discord.gg', 'api.github.com'].includes(h) || SITE_HOSTS.has(h), `unexpected destination ${h}`);
assert.match(gh.text, /no egress to api\.github\.com|could not be reached/, 'the GitHub integration test goes to api.github.com only (the egress guard refuses the socket; undici surfaces it as a fetch failure)');
assert.ok(ingested.length >= 10 && ingested.every((x) => x.path === '/internal/avatar-ingest'), `avatar imports went to Media's ingest instead (${ingested.length})`);
assert.ok(ingested.some((x) => x.url === `https://127.0.0.1:${T}/a.png`), 'Media was asked to import the URL; Network did not fetch it');