Merge branch 'valid-ws' into 'main'

Filter out invalid WebSocket URLs from pool, prevent admins from setting them

Closes #276

See merge request soapbox-pub/ditto!605
This commit is contained in:
Alex Gleason 2024-12-10 23:45:58 +00:00
commit 6eaf18a890
3 changed files with 17 additions and 3 deletions

View file

@ -12,7 +12,7 @@ import { DittoEvent } from '@/interfaces/DittoEvent.ts';
import { DittoZapSplits, getZapSplits } from '@/utils/zap-split.ts';
import { AdminSigner } from '@/signers/AdminSigner.ts';
import { screenshotsSchema } from '@/schemas/nostr.ts';
import { booleanParamSchema, percentageSchema } from '@/schema.ts';
import { booleanParamSchema, percentageSchema, wsUrlSchema } from '@/schema.ts';
import { hydrateEvents } from '@/storages/hydrate.ts';
import { renderNameRequest } from '@/views/ditto.ts';
import { accountFromPubkey } from '@/views/mastodon/accounts.ts';
@ -23,7 +23,7 @@ import { updateListAdminEvent } from '@/utils/api.ts';
const markerSchema = z.enum(['read', 'write']);
const relaySchema = z.object({
url: z.string().url(),
url: wsUrlSchema,
marker: markerSchema.optional(),
});

View file

@ -33,6 +33,16 @@ const hashtagSchema = z.string().regex(/^\w{1,30}$/);
*/
const safeUrlSchema = z.string().max(2048).url();
/** WebSocket URL. */
const wsUrlSchema = z.string().refine((val) => {
try {
const { protocol } = new URL(val);
return protocol === 'wss:' || protocol === 'ws:';
} catch {
return false;
}
}, 'Invalid WebSocket URL');
/** https://github.com/colinhacks/zod/issues/1630#issuecomment-1365983831 */
const booleanParamSchema = z.enum(['true', 'false']).transform((value) => value === 'true');
@ -81,4 +91,5 @@ export {
percentageSchema,
safeUrlSchema,
sizesSchema,
wsUrlSchema,
};

View file

@ -3,6 +3,7 @@ import { Conf } from '@/config.ts';
import { DittoDatabase } from '@/db/DittoDatabase.ts';
import { DittoDB } from '@/db/DittoDB.ts';
import { internalSubscriptionsSizeGauge } from '@/metrics.ts';
import { wsUrlSchema } from '@/schema.ts';
import { AdminStore } from '@/storages/AdminStore.ts';
import { EventsDB } from '@/storages/EventsDB.ts';
import { SearchStore } from '@/storages/search-store.ts';
@ -80,7 +81,9 @@ export class Storages {
const tags = relayList?.tags ?? [];
const activeRelays = tags.reduce((acc, [name, url, marker]) => {
if (name === 'r' && (!marker || marker === 'write')) {
const valid = wsUrlSchema.safeParse(url).success;
if (valid && name === 'r' && (!marker || marker === 'write')) {
acc.push(url);
}
return acc;