mailship/test
Agent 0a5b7ad14d
All checks were successful
CI / checks (pull_request) Successful in 34s
fix: validate relay URL before calling load() and soften unhandledRejection handler
POST /notify/:id accepted an attacker-supplied relay URL with a non-ws://
scheme (e.g. http://…). The URL was passed straight to @welshman/net's
load(), whose internal batcher throws 'Invalid relay url' asynchronously
(via setTimeout). That error escaped the route's try/catch as an unhandled
rejection, triggering process.exit(1) in src/index.ts — the entire server
died. Any registered subscriber could crash the service repeatedly.

Two fixes applied (either alone breaks the attack):

1. Validate relay scheme in the route handler before calling load()
   (src/server.ts). Uses isRelayUrl() from @welshman/util, which accepts
   only wss:// and ws:// schemes. Returns 400 immediately for invalid
   URLs, preventing the bad URL from ever reaching the batcher.

2. Soften process.on('unhandledRejection') in src/index.ts to log and
   continue instead of calling process.exit(1). Defence in depth: if any
   other async error escapes a try/catch, the server stays up.

Test: test/notify-non-wss-relay-crash.test.ts — starts an ephemeral
server, creates a confirmed subscription, POSTs with http://127.0.0.1:9,
expects 400 with an error message.
2026-09-18 10:39:04 -04:00
..
cors.test.sh fix: scope CORS to browser routes only, require CORS_ORIGIN (fail closed) 2026-09-10 11:29:18 -04:00
digest-template.test.ts Standardize tests on vitest 2026-09-14 13:32:19 -04:00
event-arrival-race.test.ts Standardize tests on vitest 2026-09-14 13:32:19 -04:00
integration.sh Fix integration test: add missing CORS_ORIGIN env var 2026-09-14 13:07:16 -04:00
normalize-relay-url.test.ts Standardize tests on vitest 2026-09-14 13:32:19 -04:00
notify-non-wss-relay-crash.test.ts fix: validate relay URL before calling load() and soften unhandledRejection handler 2026-09-18 10:39:04 -04:00
notify-response-shape.test.ts POST /notify/🆔 standardize response shape — always include stored field 2026-09-14 13:42:11 -04:00
reschedule-on-frequency-change.test.ts Standardize tests on vitest 2026-09-14 13:32:19 -04:00
setup.ts Standardize tests on vitest 2026-09-14 13:32:19 -04:00