Closed Bug 1437919 Opened 6 years ago Closed 6 years ago

it's possible to send invisible push notifications

Categories

(Core :: DOM: Push Subscriptions, defect)

57 Branch
defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: zohar, Unassigned)

Details

Attachments

(2 files)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36

Steps to reproduce:

I've registered a service worker to handle push notifications, 
that doe's show notifications.  Instead, the service worker just hooks the 'push' event and  sends HTTP post message to a third party when a notification arrives. 




Actual results:

The browser doe's not display any warning to the user, and simply sends an 'invisible'  HTTP request (i.e. an HTTP request is sent in the background according to the attacker's chooise without any user interaction) 




Expected results:

According to the specifications, the notifications must not be invisible. Note that Chrome does not allow it, and when an notification arrives and not displayed, chrome notifies the user with a warning message ('this site has been updated in the background') 

The risk here is that the attacker gains 'invisible' control over the user's browser. A collection of such browsers can be used as an 'invisible' botnet for example to launch DDOS attacks against a target, where Mozilla servers as the CNC. 



Thanks,
Zohar
Attachment #8950611 - Attachment mime type: application/javascript → text/javascript
Flagging this up to service worker folks...
Flags: needinfo?(catalin.badea392)
Flags: needinfo?(bkelly)
(In reply to Zohar from comment #0)
> User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
> (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
> 
> Steps to reproduce:
> 
> I've registered a service worker to handle push notifications, 
> that doe's show notifications.  Instead, the service worker just hooks the
> 'push' event and  sends HTTP post message to a third party when a
> notification arrives. 

Can you point out where it says this in the spec?  I don't think it does.  We explicitly chose to throttle push notifications instead of the "must show a notification" approach chrome chose.  AFAIK the spec allows this.

For example, I see a `userVisibleOnly` property in PushSubscriptionOptions, but we don't implement it:

https://w3c.github.io/push-api/#dom-pushsubscriptionoptions

Adding Martin and Kit from the team that first implemented push.
Flags: needinfo?(zohar)
Flags: needinfo?(catalin.badea392)
Flags: needinfo?(bkelly)
(In reply to Zohar from comment #0)
> According to the specifications, the notifications must not be invisible.

Sorry, meant to quote this part in my question in comment 4.
This is intentional.  We allow a small number of pushes that don't generate user-visible activity.  If a site does this too often, we will stop passing them the event.

Nothing in the specifications forbids this.
Status: UNCONFIRMED → RESOLVED
Closed: 6 years ago
Resolution: --- → INVALID
Group: firefox-core-security
Component: Untriaged → DOM: Push Notifications
Product: Firefox → Core
Hey guys, 
sorry, I was under the impression that you see eye to eye with Chrome's approach but I might have been mistaken. Thanks for your quick reply!

I would add though that there is a security issue to consider here: 
A malicious site can register users to a 'push-based' bot-net. 
The attacker can then use this botnet to launch DDoS attacks from the victim's browser, 
in essence using Mozilla as a CNC server.   
This of course is an inherent risk of using push notifications and can be also exploited via Chrome, only that in this case the users will be blind to the attack originating from their own browsers. 

Anyway, 
thank you for your reply!
Flags: needinfo?(zohar)
Hi Zohar! Sorry for the delay in replying; Martin gave a good, concise answer in comment 6.

The long answer is, we have a quota system that gives sites some leeway to handle `push` events without showing notifications. This lets sites collapse or hide stale notifications, and do work like update caches, or send messages to controlled pages. The quota is per-origin, recalculated for every incoming push, decays based on the last visit date, and has a low cap. (It's also not enforced if you have the page open, since the page could just open a WebSocket, or make requests as it wants). If the page never shows notifications, we'll silently remove its push subscription, and it won't be able to resubscribe or receive pushes until some time after you visit it again.

I think Chrome currently allows silent pushes via the Budget API (https://wicg.github.io/budget-api/, https://developers.google.com/web/updates/2017/06/budget-api), which is based on an opaque engagement score. It's similar to our approach, except we do this implicitly (it's not possible for a service worker to see how many silent pushes it has left, or be notified that we're about to remove its subscription)...and we don't implement the Budget API yet.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: