source: Klonkt/test/ssrf-allowlist.test.js

main
Last change on this file was df7de6e, checked in by Robin <roboburr@…>, 2 weeks ago

Opsplitsing stap 3 (shaer-drc): het transport naar ap-transport.js

De SSRF-poort, de RSA-sleutels per actor, HTTP Signatures (tekenen en
controleren), de bezorging met wachtrij en backoff en de ondertekende GET
verhuizen als een blok -- 381 regels, byte-voor-byte -- uit
ActivityPubService.js. Die her-exporteert alles, dus elke bestaande
importeur blijft werken; het uitvoeroppervlak is voor en na identiek
gemeten (199 named exports, 180 sleutels op het default-object), en de
afhankelijkheden van het nieuwe bestand wijzen alleen omlaag (db, ap-core,
Node zelf).

Eén toets moest mee: de cache-gebuste herimport in ssrf-allowlist.test.js
moet het bestand raken waar AP_ALLOW_HOSTS bij het laden bevroren wordt,
en dat is nu ap-transport.js.

  • Property mode set to 100644
File size: 3.2 KB
Line 
1// De SSRF-poort mag gericht open voor een testkudde op de eigen machine
2// (shaer-6wt, Barts vraag 8-8: "waarom via https? gewoon localhost ::1").
3//
4// Wat hier bewaakt wordt is de SMALHEID. De bescherming bestaat omdat een
5// actor-URI van een vreemde komt; een brede "loopback mag"-vlag zou hem in een
6// dev-omgeving uitzetten, en dev-omgevingen worden productie. Een lijst van
7// precieze host:poort-paren opent precies wat erin staat en niets ernaast.
8//
9// Run: npm test
10import { test } from 'node:test';
11import assert from 'node:assert/strict';
12
13process.env.DATABASE_PATH = ':memory:';
14// Een poort waar met opzet NIETS op luistert. Eerst stond hier 3060, en toen de
15// testkudde daar ging draaien slaagde de fetch en viel de toets om -- een toets
16// die afhangt van wat er toevallig draait, bewijst niets.
17process.env.AP_ALLOW_HOSTS = '[::1]:59321';
18const AP = await import('../src/services/ActivityPubService.js');
19
20const faalt = async (url) => {
21 try { await AP.safeFetch(url); return null; }
22 catch (e) { return e.message; }
23};
24
25test('wat er WEL op staat komt langs de poort', async () => {
26 // De slaagtest, en zonder hem is de rest waardeloos: alleen weigeringen
27 // toetsen laat de suite groen terwijl er niets doorheen komt. Er draait hier
28 // niets op 3060, dus we verwachten een VERBINDINGSfout -- het bewijs is dat
29 // het geen ssrf-fout is.
30 const fout = await faalt('http://[::1]:59321/niets');
31 assert.ok(fout, 'er is wel een fout, want er luistert niets op die poort');
32 assert.ok(!String(fout).startsWith('ssrf-'), `door de poort, maar kreeg: ${fout}`);
33});
34
35test('een adres dat NIET op de lijst staat blijft geweigerd', async () => {
36 // Zelfde machine, andere poort. Zou dit doorlaten, dan is de lijst een vlag.
37 assert.equal(await faalt('http://[::1]:3060/u/w001'), 'ssrf-blocked-ip');
38});
39
40test('en 127.0.0.1 evenmin, ook al is het dezelfde machine', async () => {
41 // De lijst opent een HOST:POORT, geen begrip van "lokaal".
42 assert.equal(await faalt('http://127.0.0.1:59321/niets'), 'ssrf-blocked-ip');
43});
44
45test('het metadata-adres blijft dicht', async () => {
46 // Waar de bescherming voor bestaat.
47 assert.equal(await faalt('http://169.254.169.254/latest/meta-data/'), 'ssrf-blocked-ip');
48});
49
50test('zonder de omgevingsvariabele is er geen uitzondering', async () => {
51 // De lijst is leeg tenzij iemand hem expliciet vult. Dit is de stand waarin
52 // elke productie-instance draait.
53 //
54 // De verse import moet het bestand raken waar AP_ALLOW_HOSTS bij het LADEN
55 // wordt bevroren, en dat is sinds de opsplitsing ap-transport.js. Een
56 // gebuste import van ActivityPubService.js zou niets bewijzen: zijn eigen
57 // `import './ap-transport.js'` (zonder query) komt uit de modulecache, met
58 // de lijst van hierboven er nog in.
59 const eerder = process.env.AP_ALLOW_HOSTS;
60 delete process.env.AP_ALLOW_HOSTS;
61 const mod = await import(`../src/services/ap-transport.js?leeg=${Date.now()}`);
62 let fout = null;
63 try { await mod.safeFetch('http://[::1]:59321/niets'); } catch (e) { fout = e.message; }
64 assert.equal(fout, 'ssrf-blocked-ip');
65 process.env.AP_ALLOW_HOSTS = eerder;
66});
67
68test('een ander schema blijft hoe dan ook geweigerd', async () => {
69 assert.equal(await faalt('file:///etc/passwd'), 'ssrf-bad-scheme');
70});
Note: See TracBrowser for help on using the repository browser.