Subject: Re: [BEHAVE] TURN: Are unauthenticated indications and ChannelData msgs a problem?

From: Cullen Jennings <[email-masked]>
Date: Tue, 1 Apr 2008 22:51:16 -0700

It's seems that one possible solution to these would be "only  
authenticated requests can create, update, or remove a permission".

Cullen <with my individual hat on>

On Mar 25, 2008, at 7:26 AM, Philip Matthews wrote:
>
> On Tue, 25-Mar-08, at 07:58 , Benny Prijono wrote:
>> On 3/24/08, Philip Matthews <[email-masked]> wrote:
>>> What are the consequences of not authenticating indications and
>>> ChannelData messages? I see two:
>>> 1) An attacker can inject fake data packets to the server or the
>>> client.
>>> 2) At attacker can refresh permissions and channels.
>>>
>>
>> What about:
>> 3) Attacker can create new permission to arbitrary peer to send rogue
>> data to client
>> 4) Attacker can DOS the server by tricking it into creating so
>> many permissions
>>
>> If he can fake source IP address/port, then he just sends a Send
>> Indication with arbitrary peer address to create a new permission,  
>> no?
>
> Good point! These are indeed attacks that I had not previously
> considered.
>
> I think these are lightly more serious than my attack (2), but I
> still don't see why someone would bother with these attacks.
>
> - Philip
> _______________________________________________
> Behave mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/behave

_______________________________________________
Behave mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/behave

---

From: "Benny Prijono" <[email-masked]>
Date: Wed, 2 Apr 2008 13:13:15 +0100

On Wed, Apr 2, 2008 at 6:51 AM, Cullen Jennings <[email-masked]> wrote:
>
>  It's seems that one possible solution to these would be "only authenticated
> requests can create, update, or remove a permission".

Just to be clear with the proposal, I imagine that we will allow zero
or more PEER-ADDRESS attribute(s) to appear in Allocate and Refresh
requests, and the server will use these attributes to create or
refresh permissions. One of the interesting thing with this is that
there will be multiple instances of the same attribute to appear in a
STUN message. I don't think this is disallowed by STUN, but I don't
think there is existing usages that use this either, so it'll be
interesting to hear if it breaks implementations. For me I'm fine with
this.

There are variants to this proposal which I think are less optimized:
 - use new request/method to refresh permission. I think this is not
necessary since I presume client will want to refresh allocation when
it refreshes permission, so why not allow Refresh to refresh
permission too (with appropriate attribute to indicate which
permissions to refresh).
 - use separate requests to refresh individual permission. I think
this is too chatty.

For the proposal, I imagine the use case with ICE will be something like this:

   - caller sends Allocate with no PEER-ADDRESS (since it doesn't know
which permission to create yet). It then sends INVITE with SDP.

   - callee receives INVITE with SDP, it inspects caller's candidates
and sends Allocate (or Refresh if it's already got an allocation) with
one or more PEER-ADDRESS attributes, one for each candidate. It then
sends 18x/2xx with SDP.

   - when caller receives SDP, it'll send Refresh with one or more
PEER-ADDRESS attributes (one for each remote candidate) to create
permissions in the server. It may delay sending Send Indication to
perform connectivity check via the the TURN candidate until the
Refresh transaction completes, or it may send it immediately after the
Refresh in the best hope that the Refresh request will not get lost.
It doesn't matter for client since the Send Indication will be
retransmitted on the next ICE check retransmissions.

  - once ICE negotiation completes, and if TURN candidate is used,
client issues ChannelBind to "lock on" the permission, and the
permission refresh is taken over by ChannelBind refresh mechanism.

I think that could work, and it looks doable. It doesn't look too
complicated, and it may even simplify the timeout mechanism a bit
since now refresh is done more explicitly (no need to refresh
permission every time Send Indication or ChannelData is received). The
only complication that I can think of is if ICE negotiation is
happening for duration that is longer than the permission duration,
which in this case client has to remember to refresh the permissions.
But considering that permission lives for 5 minutes I don't think this
is an issue, ICE negotiation should complete by then. So clients only
need to create the permission once up front, and refresh only the one
that has been negotiated (via ChannelBind above for example).

And with this there is no objection to maintain Send indication
either, since it's no longer able to create permissions.

So while I'm not too keen to have yet another major modification, I
think I can accept the proposal if that makes TURN more acceptable.
The other choice is of course to ignore and just document this in
Security Consideration section, which I'm fine too.

Cheers
 Benny <with no hat on>

---

From: Philip Matthews <[email-masked]>
Date: Thu, 3 Apr 2008 15:20:25 -0400

On Wed, 2-Apr-08, at 08:13 , Benny Prijono wrote:
>> authenticated

This is one option. I call this "option C". For other options, see my  
e-mail of 24 March.

> refresh permissions.

My personal preference would be to _not_ mix this up with Allocate and  
Refresh processing. I would instead define a new transaction for  
refreshing permissions. My reasons are:
a) I think that the Allocate transaction is already complex enough;
b) We only need a mechanism for peers that have no channels bound to  
them or where there are no channels bound to the same address but  
different port (since rebinding a channel also refreshes the  
corresponding permission). Since I think most clients will use  
channels for long-term communication, the bandwidth savings from doing  
this with the Allocate and Refresh transactions is low.

One alternative that has some attraction is to generalize the Send  
method to also support request/response transactions (in the same way  
that Binding can be either request/response or indication). The Send  
request could then carry the USERNAME, REALM, NONCE, and MESSAGE- 
INTEGRITY attributes. It would also be allowed to specify either (a) a  
PEER-ADDRESS  or (b) a CHANNEL-NUMBER. The semantics of the latter  
would be to send data on that channel and refresh the channel binding  
and the corresponding permission.

This would allow a single packet to both carry the ICE keep-alive and  
refresh the TURN channel and/or permission. This packet would be an  
ICE keep-alive (= a STUN Binding indication) wrapped inside a TURN  
Send request.

[NOTE: Some may be thinking "Why do I need an ICE keep-alive if I am  
sending packets to refresh the TURN channel and permission?". There  
are two reasons: (1) Most NATs today need to be refreshed much faster  
than 5 minutes, and (2) if there is a NAT _beyond_ the TURN server  
with its private side facing the server, then a refresh transaction  
with the TURN server will not refresh the bindings on that NAT. Case  
(2) can arise in, for example, when a TURN server is located on a node  
behind a NAT, which is being considered in P2PSIP situations.]

> One of the interesting thing with this is that
Section 15 of the STUN spec says:
    Any attribute type MAY appear more than once in a STUN message.
    Unless specified otherwise, the order of appearance is significant:
    only the first occurance needs to be processed by a receiver, and  
any
    duplicates MAY be ignored by a receiver.

- Philip

---

From: "Benny Prijono" <[email-masked]>
Date: Fri, 4 Apr 2008 11:28:43 +0100

On Thu, Apr 3, 2008 at 8:20 PM, Philip Matthews
<[email-masked]> wrote:
> Refresh processing. I would instead define a new transaction for refreshing
> permissions. My reasons are:

I think it won't, since it doesn't add more allocation specification.
This would be something that the server does after it creates the
allocation, so it shouldn't add to the complexity of the Allocate
request (by too much that is).

>  b) We only need a mechanism for peers that have no channels bound to them
> or where there are no channels bound to the same address but different port
> (since rebinding a channel also refreshes the corresponding permission).
> Since I think most clients will use channels for long-term communication,
> the bandwidth savings from doing this with the Allocate and Refresh
> transactions is low.
>

Once the communication has been established, yes. In fact probably
most clients won't use this permission refresh mechanism at all once
communication has been established if it binds the peer it wants to
communicate to with a channel, since it will refresh the channel and
the corresponding permission using ChannelBind instead.

What I was referring to as chattiness is during initial ICE
negotiation. Since client doesn't know which remote candidate will
reach it's TURN candidate, basically it has to open a permission to
each of the remote candidate (probably three at minimum), and this
would mean individual requests to open permission for each candidate.
And multiply that with the number of components. Considering that many
things are happening during ICE negotiation (lots of packets get
sent), this may be something we need to consider.

>
>  One alternative that has some attraction is to generalize the Send method
> to also support request/response transactions (in the same way that Binding
> can be either request/response or indication). The Send request could then
> carry the USERNAME, REALM, NONCE, and MESSAGE-INTEGRITY attributes. It would
> also be allowed to specify either (a) a PEER-ADDRESS  or (b) a
> CHANNEL-NUMBER. The semantics of the latter would be to send data on that
> channel and refresh the channel binding and the corresponding permission.
>
> refresh the TURN channel and/or permission. This packet would be an ICE
> keep-alive (= a STUN Binding indication) wrapped inside a TURN Send request.

For me, the concept of sending a data with a request is not too
appealing considering the size of the payload that potentially needs
to be retransmitted, and retransmission may cause the payload to
arrive out of order in the peer. The later probably is not too much of
a concern, but the former is. An ICE Binding request is about 100
bytes in length, and add that to about 100 bytes of typical long-term
authenticated TURN request. And considering that a long term request
may get challenged (e.g. expired NONCE), the figure starts to get
worrying.

Also IMO, sending ICE inside Send request looks complicated. First,
the ICE keep-alive and TURN permission timer run independently, so I
imagine each will be sent independently from one another. And second,
one needs to be careful with using Send request with ICE in general,
since the Send payload maybe a STUN request in itself (say a Binding
request), which will be retransmitted independently from the Send
request. A buggy client may end up creating a Send request for every
Binding request (the payload of Send request) retransmissions.

So with this, what most client do probably is to send a blank Send
request (containing no DATA) just to open/refresh the permission, then
use Send Indication as usual to send data. Which negates the
motivation of having Send request in the first place.

Perhaps there are other uses for this. But IMO probably it's better to
invent an explicit method to refresh permission. That's your option C
I believe. Or as a variant of option C, we also have an option to not
provide any mechanism to refresh permission and instead force everyone
to use channels. In some way this may be simpler since now there is
only one mechanism to refresh permission/channel, but it may cause
concern for long term allocation with the limited number of channel
number space. I was one of the people who argued about using long term
allocation, and in the end I decided that this was not a good idea, so
this option sounds quite feasible.

So to put all the new options on the table (in addition to your
previous mail in this thread):
 - Option F: allow Allocate and Refresh with multiple PEER-ADDRESS
attributes to create/refresh permissions
 - Option G: not to provide mechanism to refresh permission alone, and
instead force everyone to use channels (variant of option C)
 - Option H: use Send request

> sending packets to refresh the TURN channel and permission?". There are two
> reasons: (1) Most NATs today need to be refreshed much faster than 5
> minutes, and (2) if there is a NAT _beyond_ the TURN server with its private
> side facing the server, then a refresh transaction with the TURN server will
> not refresh the bindings on that NAT. Case (2) can arise in, for example,
> when a TURN server is located on a node behind a NAT, which is being
> considered in P2PSIP situations.]
>
>
>
>    only the first occurance needs to be processed by a receiver, and any

Yeah, but it says "Unless specified otherwise".

Cheers
 Benny

---

From: Philip Matthews <[email-masked]>
Date: Mon, 7 Apr 2008 18:53:31 -0400

> instead force everyone to use channels (variant of option C)

Hmmm. This option has some appeal, especially since it would suggest  
that we should remove Send indications at the same time, since their  
usefulness would go down a lot. This option would solve the problem  
AND simplify the protocol.  The only drawback would be the larger  
number of channels allocated (presumably some just temporarily while  
doing ICE connectivity checks) but is this really bad?

- Philip

---

From: Cullen Jennings <[email-masked]>
Date: Tue, 8 Apr 2008 08:11:39 -0700

I think I would need to seem more details on some of these before I  
could figure out which one looked like the best path.

---

From: "Benny Prijono" <[email-masked]>
Date: Tue, 8 Apr 2008 16:18:01 +0100

On Mon, Apr 7, 2008 at 11:53 PM, Philip Matthews
<[email-masked]> wrote:
>  Hmmm. This option has some appeal, especially since it would suggest that
> we should remove Send indications at the same time, since their usefulness
> would go down a lot. This option would solve the problem AND simplify the
> protocol.  The only drawback would be the larger number of channels
> allocated (presumably some just temporarily while doing ICE connectivity
> checks) but is this really bad?

I guess probably no, even for long term allocation. I don't suppose
people will use all the available channels simultaneously, and the 10
minutes channel life time should allow expired channels to be reused.
While this simplifies the protocol, this would make client
implementation slightly more complicated though.

Cheers
 Benny

---

From: Philip Matthews <[email-masked]>
Date: Tue, 8 Apr 2008 15:18:34 -0400

> implementation slightly more complicated though.

Why would the client be more complicated, and do you think this is  
serious?

- Philip

---

From: "Benny Prijono" <[email-masked]>
Date: Tue, 8 Apr 2008 23:52:51 +0100

On Tue, Apr 8, 2008 at 8:18 PM, Philip Matthews
<[email-masked]> wrote:
> that
>  Why would the client be more complicated, and do you think this is serious?
>

Few questions that I have in mind e.g.
 - should client ChannelBind to all remote candidates before starting
any connectivity checks, or one by one upon sending the first check
using the relay so that there's a gap between ChannelBind requests. (I
tend to say the later).
 - If it does the later, should the ICE check be embedded inside
ChannelBind (assuming ChannelBind can carry DATA), or in separate
ChannelData. (I tend to prefer the later)
 - If the later, what will happen to the first ChannelData's, would it
be wiser to sent them immediately after ChannelBind request, or to
drop them until client receives ChannelBind response? (I think i would
just send ChannelData right after ChannelBind and hope for the best.)
 - And what should (an ICE) client do if ChannelBind fails? (I think
I'll mark the check as failed.)

Not sure how serious that would be, but my feeling is it's implementable.

cheers
 -benny

---

From: Philip Matthews <[email-masked]>
Date: Wed, 9 Apr 2008 09:55:17 -0400

On Tue, 8-Apr-08, at 18:52 , Benny Prijono wrote:
>>>> would go down a lot. This option would solve the problem AND  
>>>> simplify
>> the

I would suggest doing the former as it eliminates the concerns in your  
next two points below. Furthermore, it will make the ICE checks run  
faster -- one of the things that makes ICE checks slow is waiting for  
both ends to install the necessary permissions to get connectivity- 
check packets through.

> ChannelData. (I tend to prefer the later)

The latter is what we have today, and with my comment above, I don't  
currently see any reason to change it.

> just send ChannelData right after ChannelBind and hope for the best.)

For a TURN candidate, I might consider binding the channel as part of  
the candidate gathering process. This ensures the binding is completed  
before the checks start and eliminates any concern about the binding  
not being ready when sending a connectivity check packet.

> I'll mark the check as failed.)

If it fails for anything other than an authentication challenge, then  
I think you probably want to abort the entire allocation and try  
again, because this probably means there is something out of sync  
between the client and the server.

- Philip