aboutsummaryrefslogtreecommitdiff
path: root/src/lib/Utility/pushEndpoint.ts
blob: 702164ae1b86ce708bce456b99c8a6f5a2882118 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
 * Web Push endpoints are minted by the browser's PushManager and always point at
 * a known vendor push service — the user and the app never choose them. Limiting
 * outbound delivery to these hosts stops the notifications job from being used as
 * an SSRF primitive: a stored subscription with an arbitrary `endpoint` would
 * otherwise have the worker POST to any URL, including internal/metadata hosts.
 */
const allowedPushHosts: RegExp[] = [
	/^fcm\.googleapis\.com$/, // Chrome, Edge, Brave, Opera, Samsung Internet
	/(^|\.)push\.services\.mozilla\.com$/, // Firefox
	/^web\.push\.apple\.com$/, // Safari / Apple
	/(^|\.)notify\.windows\.com$/, // legacy Edge / Windows (WNS)
];

export const isAllowedPushEndpoint = (endpoint: string): boolean => {
	try {
		const url = new URL(endpoint);

		return (
			url.protocol === "https:" &&
			allowedPushHosts.some((host) => host.test(url.hostname))
		);
	} catch {
		return false;
	}
};