fix(federation): close re-attach final-review findings — client/server domain normalization, merge attachment repoint, empty-domain guard, test hardening

This commit is contained in:
Jannis Braun
2026-07-03 02:43:45 +02:00
parent 521aff6e52
commit d3af4f2170
9 changed files with 109 additions and 7 deletions
@@ -37,6 +37,30 @@ describe('verifyAttachProofWithPeer', () => {
expect(await verifyAttachProofWithPeer(PEER, 'a'.repeat(64))).toEqual({ valid: false });
});
it('treats a PRESENT-but-INVALID signature as valid:false (signature must verify against the peer secret)', async () => {
// A 200 response with a well-formed signature header that was computed with
// the WRONG secret — it must NOT verify against the peer's real secret. This
// hardens the core "never trust unauthenticated bodies" gate: a malicious or
// misconfigured peer that returns valid:true with a bogus signature is rejected.
const wrongSignedResponse = (bodyObj: object): Response => {
const body = JSON.stringify(bodyObj);
const ts = Date.now();
const nonce = 'resp-nonce';
const sig = signRequest(body, 'c'.repeat(64) /* wrong secret */, ts, nonce);
return new Response(body, {
status: 200,
headers: {
'x-federation-signature': `sha256=${sig}`,
'x-federation-timestamp': String(ts),
'x-federation-nonce': nonce,
},
});
};
vi.stubGlobal('fetch', vi.fn(async () => wrongSignedResponse({ valid: true, homeUserId: 'h1', username: 'youruser' })));
const { verifyAttachProofWithPeer } = await import('./federationAttach.js');
expect(await verifyAttachProofWithPeer(PEER, 'a'.repeat(64))).toEqual({ valid: false });
});
it('network error → valid:false', async () => {
vi.stubGlobal('fetch', vi.fn(async () => { throw new Error('ECONNREFUSED'); }));
const { verifyAttachProofWithPeer } = await import('./federationAttach.js');
@@ -56,9 +80,15 @@ describe('fetchHomeProfileByHomeId', () => {
expect(result?.profile.avatar).toBe('a.webp');
});
it('found:false or network error → null', async () => {
it('found:false → null', async () => {
vi.stubGlobal('fetch', vi.fn(async () => new Response(JSON.stringify({ found: false }), { status: 200 })));
const { fetchHomeProfileByHomeId } = await import('./federationAttach.js');
expect(await fetchHomeProfileByHomeId(PEER, 'h1')).toBeNull();
});
it('network error → null', async () => {
vi.stubGlobal('fetch', vi.fn(async () => { throw new Error('ECONNREFUSED'); }));
const { fetchHomeProfileByHomeId } = await import('./federationAttach.js');
expect(await fetchHomeProfileByHomeId(PEER, 'h1')).toBeNull();
});
});