VDB
EN
MEDIUM 6.4

GHSA-2g9c-vf8h-prxx

Decidim: Push subscriptions can be abused for server-side requests

상세

## Description

The push-subscription endpoint stores an attacker-controlled delivery URL, and the notification send path becomes an outbound-request sink when VAPID delivery is enabled. The practical result is an authenticated, stored, mostly blind SSRF primitive to arbitrary HTTPS endpoints reachable from the app server.

## Technical description When VAPID delivery is enabled, the notification subscription flow stores the client-supplied push endpoint without checking that it belongs to an approved push service. The send path later passes that stored URL to `WebPush.payload_send`, turning the subscription into an attacker-controlled outbound request destination. This is the source-to-sink chain:

1. Source: attacker-controlled `subscription.endpoint` in the JSON body posted to `POST /notifications_subscriptions`. 2. Persistence: `params[:endpoint]` is stored under `user.notification_settings["subscriptions"]`. 3. Retrieval: `user.notifications_subscriptions.values` returns that stored endpoint later. 4. Sink: `build_payload` sets `endpoint: subscription["endpoint"]`. 5. Outbound request: `WebPush.payload_send(**payload)` uses the attacker-supplied endpoint as the destination.

One spec asserts that the endpoint is persisted exactly as supplied:

```ruby # decidim-core/spec/services/decidim/notifications_subscriptions_persistor_spec.rb expect(user.notifications_subscriptions["auth_code_121"]["endpoint"]).to eq(params[:endpoint]) ```

Another spec asserts that `SendPushNotification` passes the stored endpoint into `WebPush.payload_send`:

```ruby # decidim-core/spec/services/decidim/send_push_notification_spec.rb first_notification_payload = { message:, endpoint: subscriptions["auth_key_1"]["endpoint"], p256dh: subscriptions["auth_key_1"]["p256dh"], auth: subscriptions["auth_key_1"]["auth"], vapid: a_hash_including(...) } expect(WebPush).to receive(:payload_send).with(first_notification_payload) ```

### Impact

- In a configured deployment, an authenticated user can register an attacker-controlled or otherwise unauthorized HTTPS URL. - The server then sends outbound `POST` requests there whenever a notification is pushed. - This is a stored, mostly blind SSRF primitive: useful for outbound interaction with attacker infrastructure and, where routable, internal HTTPS services. - Notification metadata is disclosed to the supplied endpoint through the encrypted web push request path.

### Patches

See https://github.com/decidim/decidim/pull/16714.

### Workarounds

Disable the push notifications feature by removing the VAPID keys in the server.

### Resource

SSRF

### Credits

This issue was discovered in a security audit organized by the [Decidim Association](https://decidim.org) and made by [Radically Open Security](https://www.radicallyopensecurity.com/) against Decidim financed by [NGI](https://ngi.eu/).

이 버전이 영향받나요?

사용 중인 패키지 버전을 입력하면 즉시 평가합니다.

영향 패키지

RubyGems / decidim-core
최초 영향 버전: 0 수정 버전: 0.30.9
수정 bundle update decidim-core
RubyGems / decidim-core
최초 영향 버전: 0.31.0.rc1 수정 버전: 0.31.5
수정 bundle update decidim-core
RubyGems / decidim-core
최초 영향 버전: 0.32.0.rc1 수정 버전: 0.32.0
수정 bundle update decidim-core

참고