Subject: Secdir last call review of draft-ietf-jmap-core-12

From: Tero Kivinen <[email-masked]>
Date: Thu, 03 Jan 2019 04:03:58 -0800

Reviewer: Tero Kivinen
Review result: Has Issues

I have reviewed this document as part of the security directorate's
ongoing effort to review all IETF documents being processed by the
IESG.  These comments were written primarily for the benefit of the
security area directors.  Document editors and WG chairs should treat
these comments just like any other last call comments.

This is quite complicated JSON based meta application protocol, which
allows all kind of operations to be done on the server. The security
considerations lists most of the security concerns, including the fact
that owner of the account can use push event notifications to cause
denial of service attacks against 3rd party.

Instead of just pointing it out, I think we should disallow that kind
of DoS options, i.e., I think the push subscription needs to be
extended to include initial verification step, i.e., when client
registers a PushSubscription the server should immediately send one
"event" notifying the creation of the push subscription and then when
client sees that event it could verify that it can see it (this would
also allow easy way to find out whether the given url actually works)
and send verification token given in the first event back to server
confirming that it can actually see the events.

This would forbid client to set up denial service attacks against 3rd
parties, and would also verify that the event channel is actually
working, i.e. the url is accessible by the server and that the keys
are correct etc.

This document also has quite a lot of privacy concerns which are not
addressed by it. For example email delivery and event notifications can
leak lots of information even to passive attackers. I.e., if someone
can see that wikileaks smtp server sends email to corporate smtp
server, but the smtp traffic is encrypted so they do not know the
recipient of the email, but then few seconds later see push event
notification stream going to the Joe's laptop indicating something has
happened in his mail box, they can find out the who the recipient was.

Of course sharing mailboxes between multiple users (one of the
examples given in 1.6.2), has lots of privacy issues. Perhaps some
text explaining these issues would be needed in the security
considerations section. Also I think it would be better example to say
people share calendars, not mailboxes, as sharing calendars between
different users is much more common than sharing mails.

Group mailboxes do have their uses in cases of shared support mailbox,
but it might be good idea to use that example instead of the current
text in 1.6.2. I.e., user has their own primary mailbox, and then they
also have access to shared support mailbox.

---

From: "Bron Gondwana" <[email-masked]>
Date: Sat, 05 Jan 2019 17:26:26 -0500

Hi All, sorry for the late reply - I'm on vacation with spotty internet. I am replying to the original message to retain the full CC list, but will mention things in the followup emails I have seen as well.

Regarding RFC4314 - that should definitely be referenced, but by jmap-mail, not jmap-core. I don't believe that that we should change the sharing example from mail to calendar - shared mail accounts are a common thing in the business world as well as in universities. I take exception to calling that "bad or risky behaviour", not all email is private personal email. It's not unreasonable to have another personal account shared with somebody though - the secretary use case often works like this, where the secretary has read access to the boss's Inbox. I've added the discussion to the ticket for RFC4314 anyway, and created it here:

https://github.com/jmapio/jmap/issues/274

We definitely need to document the security considerations for immediate third party push.

https://github.com/jmapio/jmap/issues/275

And look at making the push protocol have a confirmation step:

https://github.com/jmapio/jmap/issues/276

I believe that's everything from the thread - please let me know if I've missed any actions we need the authors to take.

Thanks,

Bron.

--
 Bron Gondwana, CEO, FastMail Pty Ltd
 [email-masked]

---

From: "Neil Jenkins" <[email-masked]>
Date: Sat, 05 Jan 2019 18:06:09 -0500

> https://github.com/jmapio/jmap/issues/276

I'm not convinced this is necessary and/or helpful. In the current system, the first time a push is triggered the application (JMAP) server sends a request to the push server (the URL registered by the client); if this is not accepted with a reasonable HTTP response, it would automatically disable it. The danger is meant to be DOSing this URL (it's not really a push server); however with a confirmation step, you still need to do that first request so you're not reducing the number of HTTP requests. You are however relying on the push being received by the client in order for it to be able to complete registration, and all common push services do not guarantee delivery, so this becomes much less reliable. (With this in mind, the JMAP push system happily copes with dropped push packets while still guaranteeing full resynchronisation.)

I note this issue doesn't really seem to be specific to JMAP, and yet RFC8030 (which is what the push system is implementing) does not require a confirmation step.

Neil.

---

From: "Bron Gondwana" <[email-masked]>
Date: Sun, 06 Jan 2019 05:57:43 -0500

> I note this issue doesn't really seem to be specific to JMAP, and yet RFC8030 (which is what the push system is implementing) does not require a confirmation step.

Tero - are you satisfied with this response? The fact that RFC8030 didn't see the need to add a confirmation step suggests that not having a confirmation step in JMAP isn't wildly different from current practice or current IETF standards, and Neil's justification that it makes setup less reliable for common push services seems reasonable.

If we need to beef up the language that the server MUST disable the push channel if the endpoint URL doesn't reply correctly, and maybe even a suggestion that the server rate limit individual authenticated users and similarly detect weird behaviour and limit it. It would be great to solve this with clear advice to server implementations on how to not become a DOS amplifier rather than hobble the protocol.

Cheers,

Bron.

---

From: Tero Kivinen <[email-masked]>
Date: Mon, 7 Jan 2019 15:17:50 +0200

Neil Jenkins writes:
> I'm not convinced this is necessary and/or helpful. In the current system, the
> first time a push is triggered the application (JMAP) server sends a request to
> the push server (the URL registered by the client); if this is not accepted
> with a reasonable HTTP response, it would automatically disable it. The danger
> is meant to be DOSing this URL (it's not really a push server); however with a
> confirmation step, you still need to do that first request so you're not
> reducing the number of HTTP requests. You are however relying on the push being
> received by the client in order for it to be able to complete registration, and
> all common push services do not guarantee delivery, so this becomes much less
> reliable. (With this in mind, the JMAP push system happily copes with dropped
> push packets while still guaranteeing full resynchronisation.)

Actually I think adding confirmation step will make the push
notifications more reliable, as that will give you positive feedback
that your push notifications do work. It is really annoying trying to
debug which firewall / proxy / encryption is causing the notification
to be blocked, if I need to reregister again for every time and need
to then somehow still cause one push notification to be sent before I
can see does it work. 

> I note this issue doesn't really seem to be specific to JMAP, and yet RFC8030
> (which is what the push system is implementing) does not require a confirmation
> step.

My understanding is that RFC8030 does not connect random urls, the
push notifications are received by client doing GET request to the
subscription server and then later server using server push to that
connection or something like that (in section 6 of the RFC8030).
Usually that is only way things can work, as most of the people are
behind firewalls / NATs / Proxies etc, thus connecting to them from
outside is impossible or hard.

The interaction between UA and the Application server is using
"an application-specific method" which is not described in the
RFC8030:

   An application-specific method is used to distribute the push URI to
   the application server.  Confidentiality protection and application
   server authentication MUST be used to ensure that this URI is not
   disclosed to unauthorized recipients (Section 8.3).

The verification would be inside this application-specific method,
thus it is not covered in the 8030 because of that.

In Jmap case the URL can be anything in the network and server is
assumed to connect to that URL every time something happens. Yes, if
something goes wrong in that url then notifications are disabled, but
if server just answers HTTP ok 200 back, and JMAP server will be
happy to keep sending notifications.

With verification step the amplification factor would be around 1, as
attacker does subscription registration (small packet), JMAP server
sends first notification indication subscription is registed to given
url (small packet), and when JMAP server does not get confirmation
back from the attacker (which most likely cannot see the
notifications), then it will delete subscription.

Attacker can also do 10000 subscriptions to same victim (perhaps using
different URLs, but destioned to same victim). It can do this
overnight, and then on the morning when someone triggers event the
victim will suddenly receive 10000 event notifications
(https-connections) from the well connected JMAP server farm, and will
be completely swamped before it can even respond to any errors to
those notifications.
-- 
[email-masked]

---

From: "Neil Jenkins" <[email-masked]>
Date: Mon, 07 Jan 2019 21:30:07 -0500

On Tue, 8 Jan 2019, at 12:17 AM, Tero Kivinen wrote:
> that your push notifications do work.

The issue is that push services (e.g. Apple's APNS and Google's FCM) do not guarantee that any particular push will be received. They normally will, but may not, especially if the device goes offline for a while. So if your first push doesn't make it through your push never works. It's likely to be rare, but painful when it happens and makes it feel unreliable.

> It is really annoying trying to debug which firewall / proxy / encryption is causing the notification to be blocked, if I need to reregister again for every time and need to then somehow still cause one push notification to be sent before I can see does it work. 

I'm not sure what you're referring to here. Do you mean the JMAP (application) server connecting to the push server? Or the push server connecting to the client (which is not part of JMAP at all, but where you're more likely to run into issues with corporate firewalls and the like)?

> My understanding is that RFC8030 does not connect random urls,

My understanding is that is incorrect. There are three entities involved in an 8030 push system, and JMAP is only involved with two of them:

 * The client, which wants to receive the push notifications (the JMAP client)
 * The application server which contains the data and wants to send the push notifications (the JMAP server) 
 * The push server (3rd party, depends on the device what is possible)

The situation of the client/application server being one entity and the push server being a completely unrelated entity is what 8030 is designed for. For example, each browser implements the Push API <https://w3c.github.io/push-api/>, whereby if you have a web app you can ask the browser for a push subscription endpoint, then send it to your application server to connect to. The application server does not know in advance which browser the user has or what domains that browser currently uses for push subscriptions. It simply gets given an arbitrary URL to post to. 

JMAP is not defining anything new here. It is just defining the application server portion exactly as expected by RFC8030.

> the push notifications are received by client doing GET request to the

Yes, this is how the client receives the data from the push server in RFC8030. This is entirely orthogonal to what we are discussing though.

> "an application-specific method" …

Hmm, yes I see your point, although it seems odd for it not to mention at all given this is going to apply to pretty much every app that uses this system; not specifically JMAP.

> but if server just answers HTTP ok 200 back, and JMAP server will be

Yes, this is indeed a risk, and I agree that a confirmation step would be the only way to mitigate this.

> be completely swamped before it can even respond to any errors to

I would expect the JMAP server to rate limit the number of push subscriptions any one user may have to something considerably lower than that. If the attacker had compromised many accounts on the JMAP server though, it could set up push subscriptions with each of them but then it would have to coordinate making a change in each of those accounts at the same time in order to flood the target server with a large single burst of requests, which is a much harder thing to do.

Summing up, I think that adding a confirmation step removes a small risk of being able to use a JMAP application server as a DDOS vector, but adds a small risk of the push not being received and the push system failing to establish. (Although, the client would at least know this was the case so could alert the user and give them the option to try again.) Would anyone else like to weigh in on the relative merits of the options here to help come to a consensus on the way forward? I would be particularly interested to hear if this was discussed at all, and any conclusions reached, in the development of RFC8030.

Neil.

---

From: Tero Kivinen <[email-masked]>
Date: Tue, 8 Jan 2019 16:28:05 +0200

Neil Jenkins writes:
> The issue is that push services (e.g. Apple's APNS and Google's FCM) do not
> guarantee that any particular push will be received. They normally will, but
> may not, especially if the device goes offline for a while. So if your first
> push doesn't make it through your push never works. It's likely to be rare, but
> painful when it happens and makes it feel unreliable.

When you are subscribing the push notifications your devices should be
running and not offline. Note, that you do not need reconfirmation if
you extended the time, but only when new URL is given. If client gives
url, it should make sure it can actually receive those notifications
in the given url for few seconds... 

>     It is really annoying trying to debug which firewall / proxy / encryption
>     is causing the notification to be blocked, if I need to reregister again
>     for every time and need to then somehow still cause one push notification
>     to be sent before I can see does it work. 
> 
> I'm not sure what you're referring to here. Do you mean the JMAP (application)
> server connecting to the push server? Or the push server connecting to the
> client (which is not part of JMAP at all, but where you're more likely to run
> into issues with corporate firewalls and the like)?

Perhaps my understanding of the jmap push service is then wrong, or
perhaps it is badly defined in JMAP. 

> My understanding is that is incorrect. There are three entities involved in an
> 8030 push system, and JMAP is only involved with two of them:
> 

But client and application server protocol is not defined in RFC8030.
It is left outside the scope of that document. RFC8030 seems to only
document interaction between the client and push service, and
interaction between application and push service.

The URL returned from the push service is somehow magically given to
the application server and whatever verification happens there is not
covered. 

> The situation of the client/application server being one entity and the push
> server being a completely unrelated entity is what 8030 is designed for. For
> example, each browser implements the Push API, whereby if you have a web app
> you can ask the browser for a push subscription endpoint, then send it to your
> application server to connect to. The application server does not know in
> advance which browser the user has or what domains that browser currently uses
> for push subscriptions. It simply gets given an arbitrary URL to post to.

Looking at the text in jmap. It says in section 7.2:

   A push subscription is a message delivery context established between
   the client and a push service.

Push service is not defined in this document, and it does not refer to
RFC8030 for that term. My understanding was that push worked as
follows:

Client does PushSubscription as defined in 7.2 to JMAP server:

   Clients may create a push subscription on the JMAP server, which will
   then make a POST request to the associated push endpoint whenever an
   event occurs.

This push subscription includes an url and when something happens the
JMAP server will connect to that url and send some random garbage
(from the receiver point of view if it does not assume receiveing push
notications) to it using POST. If the receiver end is proper push
service then it will notify the client using some other means.

I.e., when email etc is received the JMAP server will then push
StateChange object (section 7.1):

   When something changes on the server, the server pushes a
   *StateChange* object to the client.

Actually that says "to the client" not to the "push service". Which
one should it be? I always assumed this StateChange object is sent to
the url given in the PushSubscription.

Hmm... and 7.2 then also uses term "push endpoint" which is not
defined anywhere? Is that the same as push service at given url or
something else:

   Clients may create a push subscription on the JMAP server, which will
   then make a POST request to the associated push endpoint whenever an
   event occurs.

Then section 7.2 seems to also describe things not related to the
PushSubscription but instead to the notifications sent by the JMAP
server. Perhaps it would be better to move that to the StateChange
object section, i.e., put all things related to the "push service" in
same place. Now it is split in two places, i.e., StateChange is
defined in section 7.1, but how to transmit that inside https POST
with content type of application/json is described in 7.2.

Also it is not clear which server this is talking about:

							The server
   is expected to understand and handle HTTP status responses in a
   reasonable manner.

Is it push service server, JMAP server, Application server (same as
JMAP server in this case?). My guess it is supposed to be JMAP server
which is actually acting as http-client and making https request to
push service, and if push service returns http errors JMAP server
acting as http-client will process those in reasonable manner. Is that
understaning correct? Perhaps rewording it a bit to make it clear.

Then I have no idea what this text is trying to say:

   The use of this push endpoint conforms with the use of a push
   endpoint by an Application Server as defined in [RFC8030].

what push endpoint? JMAP server? URL given by the client to JMAP
server? 

> JMAP is not defining anything new here. It is just defining the application
> server portion exactly as expected by RFC8030.
> 
> Yes, this is how the client receives the data from the push server in RFC8030.
> This is entirely orthogonal to what we are discussing though.
> 
> Hmm, yes I see your point, although it seems odd for it not to mention at all
> given this is going to apply to pretty much every app that uses this system;
> not specifically JMAP.

Most likely it is not describied in the RFC8030 because the details
depends on the application server. 

> would be the only way to mitigate this.

I would expect it to be very easy to find urls in host that will
return success to http posts with application/json and ignore
contents.

> I would expect the JMAP server to rate limit the number of push
> subscriptions any one user may have to something considerably lower
> than that.

There is text saying frequency of pushes to be rate limited, but there
is no limit for number of subscriptions account can have, or even
suggestion that there should be limit.

This kind of attacks can also use multiple accounts especially if
there is some kind of public services available. 

> If the attacker had compromised many accounts on the JMAP
> server though, it could set up push subscriptions with each of them
> but then it would have to coordinate making a change in each of
> those accounts at the same time in order to flood the target server
> with a large single burst of requests, which is a much harder thing
> to do.

As people pointed out we have imap server providing access to ietf
mailing lists. There is lots of people on those lists, and even if we
require datatracker account to be able to make subscriptions, making
those accounts require just email address and ability to receive
emails. Most likely datatracker allows creating accounts for:

[email-masked]
[email-masked]
[email-masked]
...
[email-masked]

and then making subscription for all of those accounts to all ietf
mailing lists and sending notifications to same url x...

Verification step would disable that attack vector too. 

> Summing up, I think that adding a confirmation step removes a small
> risk of being able to use a JMAP application server as a DDOS
> vector, but adds a small risk of the push not being received and the
> push system failing to establish.

Actually I think it will make push system much more reliable, as it
immediately verifies that the system is working, and you will not have
silent failure, where you just notice few days later that I have not
received any notifications, something must be broken.

> (Although, the client would at least know this was the case so could
> alert the user and give them the option to try again.) Would anyone
> else like to weigh in on the relative merits of the options here to
> help come to a consensus on the way forward? I would be particularly
> interested to hear if this was discussed at all, and any conclusions
> reached, in the development of RFC8030.
-- 
[email-masked]

---

From: "Neil Jenkins" <[email-masked]>
Date: Tue, 08 Jan 2019 23:18:36 -0500

On Wed, 9 Jan 2019, at 1:28 AM, Tero Kivinen wrote:
> running and not offline.

Agreed. It's still possible for the initial message not to arrive, but in the vast majority of cases it will; if it doesn't, the client can destroy and recreate the subscription to try again. Weighing this up, I agree that adding a verification step is the best way forward here.

> one should it be?

Well, it's to the client, possibly via a push service, but possibly not because there are two "push" mechanisms defined here; the other is where the client can maintain a permanent TCP connection directly to the JMAP server in which case it can use an EventSource connection to receive push events directly without going via a 3rd party.

> defined anywhere? Is that the same as push service at given url

Reading through it again, there was some confusion in the use of terminology. I have rewritten a few sections to attempt to clarify this and the other confusing points you pointed out. You can see the changes for this here <https://github.com/jmapio/jmap/commit/27d21a4bca8187fc2cdd5561ccdda01bb6e26386>. The addition of a verification step is added in this change here <https://github.com/jmapio/jmap/commit/3d5e2ea288950a57670b4446f04dab9620e8bffa>.

Are you happy that this is sufficient to address your concerns?

Regards,
Neil.

---

From: Tero Kivinen <[email-masked]>
Date: Thu, 24 Jan 2019 23:30:43 +0200

Neil Jenkins writes:
> Agreed. It's still possible for the initial message not to arrive, but in the
> vast majority of cases it will; if it doesn't, the client can destroy and
> recreate the subscription to try again. Weighing this up, I agree that adding
> a verification step is the best way forward here.
> 
> Well, it's to the client, possibly via a push service, but possibly not
> because there are two "push" mechanisms defined here; the other is where the
> client can maintain a permanent TCP connection directly to the JMAP server in
> which case it can use an EventSource connection to receive push events
> directly without going via a 3rd party.
> 
> Reading through it again, there was some confusion in the use of terminology.
> I have rewritten a few sections to attempt to clarify this and the other
> confusing points you pointed out. You can see the changes for this here. The
> addition of a verification step is added in this change here.
> 

Yes, I think this addresses my concerns about the denial of service
issues. The text also seems to make little bit more clear about the
terminology, and perhaps the Terminology section should refer to the
terms defined in the RFC8030, so it would be clear which terms comes
from there.

Sorry that it took so long to reply, but last week I was in the IEEE
meeting, thus I was not able to check these during that time.
-- 
[email-masked]