Web应用向服务器安全推送通知订阅信息的方案问询
Great question—this is a critical consideration when setting up web push, and you’re absolutely right to worry about malicious abuse of an open endpoint. Let’s break down why you shouldn’t leave it fully open, and what to do instead:
Why a fully open endpoint is dangerous
A completely unprotected POST endpoint for push subscriptions invites all sorts of trouble:
- Malicious actors could flood your database with fake or invalid subscription data, wasting storage and making it harder to manage legitimate users.
- They could trigger unnecessary push requests (if you ever broadcast to all subscriptions), draining your server resources or getting your push service flagged for spam.
- In worst cases, bad actors might use the endpoint to probe for vulnerabilities in your server setup.
Recommended solutions to secure the endpoint
You absolutely need to add an authentication layer here. Here are the most practical approaches based on your website’s setup:
1. Use user-specific authentication tokens (if you have a login system)
If your site requires users to log in, this is the most straightforward and secure option:
- When a user logs in, your server issues a short-lived, signed token (like a JWT) that the frontend stores (e.g., in
localStorageor an HTTP-only cookie). - When sending the push subscription data, include this token in the request headers.
- On the server side, validate the token’s signature, check its expiration date, and confirm it’s tied to a valid user before storing the subscription.
Example frontend code:
// After getting the push subscription const pushSubscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: 'YOUR_PUBLIC_VAPID_KEY' }); // Send to server with auth token fetch('/api/save-push-subscription', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${userAuthToken}` // Your user's valid token }, body: JSON.stringify(pushSubscription) });
2. Use short-lived one-time tokens (for public/non-login sites)
If your site doesn’t have a user login system, generate a temporary, time-limited token when the user loads the page:
- When a user visits your site, your server creates a token (with an expiration of, say, 5-10 minutes) and passes it to the frontend (e.g., via a hidden form field or a cookie).
- The frontend includes this token in the POST request when sending the subscription data.
- The server checks that the token is valid, hasn’t expired, and hasn’t been used before (if you want to make it one-time) before processing the request.
3. Add extra validation checks
On top of authentication, add these safeguards to filter bad data:
- Validate the
endpointfield in the subscription data to ensure it comes from a legitimate push service (e.g., check if it matches known domains likefcm.googleapis.comorpush.services.mozilla.com). - Rate-limit requests to the endpoint (e.g., max 3 requests per IP per minute) to prevent brute-force attacks.
- Sanitize all incoming data to avoid injection attacks.
Final takeaway
Never leave your push subscription endpoint fully open. Using short-lived, server-generated tokens (either tied to a user or a temporary session) is the best way to balance usability and security, ensuring only legitimate users can submit valid subscription data to your server.
内容的提问来源于stack exchange,提问作者stepanian

