aboutsummaryrefslogtreecommitdiff
path: root/src/trigger
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-06-01 15:37:21 +0000
committerFuwn <[email protected]>2026-06-01 15:37:21 +0000
commit662631a27948d431e6bd37fed15077b1bcccc7f8 (patch)
treeb71ddebe246ffb51fb214664233f6a38a26a6211 /src/trigger
parentfix(security): authorize shadowHide target in badges endpoint (IDOR) (diff)
downloaddue.moe-662631a27948d431e6bd37fed15077b1bcccc7f8.tar.xz
due.moe-662631a27948d431e6bd37fed15077b1bcccc7f8.zip
fix(security): allow-list web-push endpoints to stop SSRF
Stored push subscriptions carry a client-supplied `endpoint`, and the notifications job POSTed to it with no host check, so a subscription with an internal/metadata URL turned the Trigger.dev worker into a blind SSRF primitive. Add isAllowedPushEndpoint (https + known vendor hosts: FCM, Mozilla, Apple, WNS), skip non-conforming endpoints in the job, and reject them at subscribe time. Browser-minted subscriptions always match a vendor host, so real delivery is unchanged; a behaviour-gate test asserts vendor endpoints pass and internal/non-https/look-alikes fail.
Diffstat (limited to 'src/trigger')
-rw-r--r--src/trigger/notifications.ts9
1 files changed, 5 insertions, 4 deletions
diff --git a/src/trigger/notifications.ts b/src/trigger/notifications.ts
index e36f913f..3daca47e 100644
--- a/src/trigger/notifications.ts
+++ b/src/trigger/notifications.ts
@@ -1,6 +1,7 @@
import { createClient } from "@supabase/supabase-js";
import { envvars, schedules } from "@trigger.dev/sdk";
import * as webpush from "web-push";
+import { isAllowedPushEndpoint } from "../lib/Utility/pushEndpoint";
const isExpiredSubscriptionError = (error: unknown) => {
const statusCode =
@@ -94,11 +95,11 @@ export const notificationsTask = schedules.task({
for (const subscription of await getUserSubscriptions()) {
const endpoint = subscriptionEndpoint(subscription.subscription);
- if (endpoint) {
- if (seenEndpoints.has(endpoint)) continue;
+ if (!endpoint || !isAllowedPushEndpoint(endpoint)) continue;
- seenEndpoints.add(endpoint);
- }
+ if (seenEndpoints.has(endpoint)) continue;
+
+ seenEndpoints.add(endpoint);
try {
await webpush.sendNotification(subscription.subscription, ".");