diff options
| author | 饺子w (Yumechi) <35571479+eternal-flame-AD@users.noreply.github.com> | 2025-03-12 12:39:24 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-12 12:39:24 +0000 |
| commit | e5d117dc98b725f908402638754f8643bbbeef90 (patch) | |
| tree | d9a08f887d8ce217343ba5b097975de4c984d1d5 /packages/backend/test/unit | |
| parent | enhance(frontend): make deck profiles syncable (diff) | |
| download | misskey-e5d117dc98b725f908402638754f8643bbbeef90.tar.gz misskey-e5d117dc98b725f908402638754f8643bbbeef90.tar.bz2 misskey-e5d117dc98b725f908402638754f8643bbbeef90.zip | |
fix(backend): tighten an overly relaxed criteria and remove capability of matching multiple final URLs in URL authority checking (#15655)
Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
Diffstat (limited to 'packages/backend/test/unit')
| -rw-r--r-- | packages/backend/test/unit/ap-request.ts | 75 |
1 files changed, 30 insertions, 45 deletions
diff --git a/packages/backend/test/unit/ap-request.ts b/packages/backend/test/unit/ap-request.ts index 0426de8e19..f8b2a697f2 100644 --- a/packages/backend/test/unit/ap-request.ts +++ b/packages/backend/test/unit/ap-request.ts @@ -8,7 +8,7 @@ import httpSignature from '@peertube/http-signature'; import { genRsaKeyPair } from '@/misc/gen-key-pair.js'; import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js'; -import { assertActivityMatchesUrls, FetchAllowSoftFailMask } from '@/core/activitypub/misc/check-against-url.js'; +import { assertActivityMatchesUrl, FetchAllowSoftFailMask } from '@/core/activitypub/misc/check-against-url.js'; import { IObject } from '@/core/activitypub/type.js'; export const buildParsedSignature = (signingString: string, signature: string, algorithm: string) => { @@ -66,23 +66,26 @@ describe('ap-request', () => { }); test('rejects non matching domain', () => { - assert.doesNotThrow(() => assertActivityMatchesUrls( + assert.doesNotThrow(() => assertActivityMatchesUrl( 'https://alice.example.com/abc', { id: 'https://alice.example.com/abc' } as IObject, - [ - 'https://alice.example.com/abc', - ], + 'https://alice.example.com/abc', FetchAllowSoftFailMask.Strict, ), 'validation should pass base case'); - assert.throws(() => assertActivityMatchesUrls( + assert.throws(() => assertActivityMatchesUrl( 'https://alice.example.com/abc', { id: 'https://bob.example.com/abc' } as IObject, - [ - 'https://alice.example.com/abc', - ], + 'https://alice.example.com/abc', FetchAllowSoftFailMask.Any, ), 'validation should fail no matter what if the response URL is inconsistent with the object ID'); + assert.doesNotThrow(() => assertActivityMatchesUrl( + 'https://alice.example.com/abc#test', + { id: 'https://alice.example.com/abc' } as IObject, + 'https://alice.example.com/abc', + FetchAllowSoftFailMask.Strict, + ), 'validation should pass with hash in request URL'); + // fix issues like threads // https://github.com/misskey-dev/misskey/issues/15039 const withOrWithoutWWW = [ @@ -97,89 +100,71 @@ describe('ap-request', () => { ), withOrWithoutWWW, ).forEach(([[a, b], c]) => { - assert.doesNotThrow(() => assertActivityMatchesUrls( + assert.doesNotThrow(() => assertActivityMatchesUrl( a, { id: b } as IObject, - [ - c, - ], + c, FetchAllowSoftFailMask.Strict, ), 'validation should pass with or without www. subdomain'); }); }); test('cross origin lookup', () => { - assert.doesNotThrow(() => assertActivityMatchesUrls( + assert.doesNotThrow(() => assertActivityMatchesUrl( 'https://alice.example.com/abc', { id: 'https://bob.example.com/abc' } as IObject, - [ - 'https://bob.example.com/abc', - ], + 'https://bob.example.com/abc', FetchAllowSoftFailMask.CrossOrigin | FetchAllowSoftFailMask.NonCanonicalId, ), 'validation should pass if the response is otherwise consistent and cross-origin is allowed'); - assert.throws(() => assertActivityMatchesUrls( + assert.throws(() => assertActivityMatchesUrl( 'https://alice.example.com/abc', { id: 'https://bob.example.com/abc' } as IObject, - [ - 'https://bob.example.com/abc', - ], + 'https://bob.example.com/abc', FetchAllowSoftFailMask.Strict, ), 'validation should fail if the response is otherwise consistent and cross-origin is not allowed'); }); test('rejects non-canonical ID', () => { - assert.throws(() => assertActivityMatchesUrls( + assert.throws(() => assertActivityMatchesUrl( 'https://alice.example.com/@alice', { id: 'https://alice.example.com/users/alice' } as IObject, - [ - 'https://alice.example.com/users/alice' - ], + 'https://alice.example.com/users/alice', FetchAllowSoftFailMask.Strict, ), 'throws if the response ID did not exactly match the expected ID'); - assert.doesNotThrow(() => assertActivityMatchesUrls( + assert.doesNotThrow(() => assertActivityMatchesUrl( 'https://alice.example.com/@alice', { id: 'https://alice.example.com/users/alice' } as IObject, - [ - 'https://alice.example.com/users/alice', - ], + 'https://alice.example.com/users/alice', FetchAllowSoftFailMask.NonCanonicalId, ), 'does not throw if non-canonical ID is allowed'); }); test('origin relaxed alignment', () => { - assert.doesNotThrow(() => assertActivityMatchesUrls( + assert.doesNotThrow(() => assertActivityMatchesUrl( 'https://alice.example.com/abc', { id: 'https://ap.alice.example.com/abc' } as IObject, - [ - 'https://ap.alice.example.com/abc', - ], + 'https://ap.alice.example.com/abc', FetchAllowSoftFailMask.MisalignedOrigin | FetchAllowSoftFailMask.NonCanonicalId, ), 'validation should pass if response is a subdomain of the expected origin'); - assert.throws(() => assertActivityMatchesUrls( + assert.throws(() => assertActivityMatchesUrl( 'https://alice.multi-tenant.example.com/abc', { id: 'https://alice.multi-tenant.example.com/abc' } as IObject, - [ - 'https://bob.multi-tenant.example.com/abc', - ], + 'https://bob.multi-tenant.example.com/abc', FetchAllowSoftFailMask.MisalignedOrigin | FetchAllowSoftFailMask.NonCanonicalId, ), 'validation should fail if response is a disjoint domain of the expected origin'); - assert.throws(() => assertActivityMatchesUrls( + assert.throws(() => assertActivityMatchesUrl( 'https://alice.example.com/abc', { id: 'https://ap.alice.example.com/abc' } as IObject, - [ - 'https://ap.alice.example.com/abc', - ], + 'https://ap.alice.example.com/abc', FetchAllowSoftFailMask.Strict, ), 'throws if relaxed origin is forbidden'); }); test('resist HTTP downgrade', () => { - assert.throws(() => assertActivityMatchesUrls( + assert.throws(() => assertActivityMatchesUrl( 'https://alice.example.com/abc', { id: 'https://alice.example.com/abc' } as IObject, - [ - 'http://alice.example.com/abc', - ], + 'http://alice.example.com/abc', FetchAllowSoftFailMask.Strict, ), 'throws if HTTP downgrade is detected'); }); |