Subject: Re: [quicwg/base-drafts] Amplification attack using retry tokens and spoofed addresses (#2064)

From: janaiyengar <[email-masked]>
Date: Mon, 03 Dec 2018 18:03:23 -0800

@huitema: I like the rephrase you suggest ([here](https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443282924)). I might make a minor change:
```
Attackers could replay tokens to use servers as amplifiers in DDoS attacks. To protect against such attacks, servers SHOULD ensure that tokens have a short life time.  Servers that are able to should ensure that tokens are used by clients only once.
```

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443941922

---

From: MikkelFJ <[email-masked]>
Date: Tue, 04 Dec 2018 11:24:25 +0000 (UTC)

We may need some sort of linearisation if "once" is ever going to be practical, such as the client only using last received token, but I don't see how that could be accomplished in praxis. So in effect a server would need to explicitly track all outstanding tokens which may be too much even for a single server deployment.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-444066887

---

From: Marten Seemann <[email-masked]>
Date: Fri, 07 Dec 2018 06:58:49 -0800

@huitema @janaiyengar As I described in https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443087560, I don't a short token life time works as a protection here. I expect servers to issue tokens (in NEW_TOKEN frames) that have the same life time as TLS session tickets, which, if I remember correctly, is a 7 days.

The property we're really looking for here is not that a token is only used once. To prevent the DoS attacks, it would be sufficient if the server only accepts a token once **within a short time span**, let's say in the order of magnitude of 10 seconds.
If an attacker manages to obtain a copy of a token that was originally sent in a NEW_TOKEN frame, all he can do is make the server send the ServerHello and the certificate to the client every 10 seconds, which might be an annoyance, but not sufficient for a DoS attack.

I believe this is should be straightforward to implement: A server could either keep a short-lived set of tokens that were recently used, or maybe even a bloom filter which is cleared in regular intervals.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-445257931

---

From: Kazuho Oku <[email-masked]>
Date: Fri, 07 Dec 2018 10:15:14 -0800

@marten-seemann 
> I don't a short token life time works as a protection here. I expect servers to issue tokens (in NEW_TOKEN frames) that have the same life time as TLS session tickets, which, if I remember correctly, is a 7 days.

I am not sure if that's correct. IIUC, the reason we split information that are maintained across connections to TLS session tickets and tokens was because they have different properties, including lifetime. Tokens are per-path objects and they should have a short span. If that's not clear, I think we should clarify that.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-445318555

---

From: Christian Huitema <[email-masked]>
Date: Fri, 07 Dec 2018 10:58:14 -0800

@marten-seemann if I recall correctly, there was an intense discussion about 0-RTT and session ticket reuse in the TLS working group. Some forms of 0-RTT replay attacks can be prevented if session tickets are used at most once, or at least if session tickets enable 0-RTT data at most once per use. That discussion showed that at-most-once was very hard to handle in a big server farm, as it would require centralized management of state across many servers. See section 8 of RFC8446, "0-RTT and Anti-Replay" for the resulting compromise.

I understand that ensuring at-most-once with tokens might seem equally hard, although there is a possible solution in QUIC that is not available in TLS. The basic QUIC server farm architecture assumes that load balancers route packets to specific servers based on the destination CID. It should be possible to have that CID be a function of the content of the retry token. That could be as simple as allocating the destination CID before formatting the NEW TOKEN, and having that reserved CID part of the encrypted content of the token. The load balancer could then routed based on the CID decrypted from the token, and the individual server could select the destination CID based on the token. That would definitely limit token reuse.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-445331050

---

From: ianswett <[email-masked]>
Date: Fri, 07 Dec 2018 11:07:27 -0800

@huitema if I understand correctly, that requires the load balancer to have the decryption keys for the 0RTT tokens the server distributes?  That is certainly possible in some cases, but I think that will be too complex for many.

Alternately, giving out a CID with the 0RTT Token could make this a fairly easy problem to solve.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-445333716

---

From: ianswett <[email-masked]>
Date: Fri, 07 Dec 2018 11:09:44 -0800

Sorry, this PR is only for Retry tokens, nevermind my previous comment.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-445334361

---

From: Marten Seemann <[email-masked]>
Date: Fri, 07 Dec 2018 18:37:58 -0800

@huitema 
>  if I recall correctly, there was an intense discussion about 0-RTT and session ticket reuse in the TLS working group. Some forms of 0-RTT replay attacks can be prevented if session tickets are used at most once, or at least if session tickets enable 0-RTT data at most once per use. That discussion showed that at-most-once was very hard to handle in a big server farm, as it would require centralized management of state across many servers. See section 8 of RFC8446, "0-RTT and Anti-Replay" for the resulting compromise.

I think we're talking about different security properties here. QUIC tokens are designed to **only** prove reachability at a specific IP address, and don't contain any sensitive information beyond that. Token reuse is therefore only a problem **if** it can be used by an attacker to flood the client with more unwanted traffic than either the client or the network can handle at any given time.

@kazuho
> I am not sure if that's correct. IIUC, the reason we split information that are maintained across connections to TLS session tickets and tokens was because they have different properties, including lifetime.

If I remember correctly, the reason we split those was to enable token validation without parsing of the packet contents and handing it off to the TLS stack. That being said, I think you're right that tokens might have a different life time than session tickets.
Since most (?) ISPs reassign a new IP address to the customers every 24 hours (at least that's how they typically do it in Germany), a token would become worthless after this time. I'd therefore expect a NEW_TOKEN token to be valid for around that duration.

But even if this was not the case, and the token validity was just on the order of a minute, we'd have a problem here. An attacker who captures such a token can make the server send traffic with a high amplification factor to the client for the lifetime of that token.
This might even be a problem for Retry tokens, which will only be valid for a few seconds: If the attacker can cause a high load on the path to the client, it might succeed in creating enough congestion that the packets belonging to the actual handshake are dropped.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-445423431

---

From: Martin Thomson <[email-masked]>
Date: Tue, 11 Dec 2018 22:25:45 -0800

How about:

> Attackers could replay tokens to use servers as amplifiers in DDoS attacks. To protect
against such attacks, servers SHOULD ensure that tokens sent in Retry packets are only accepted for a short time.  Tokens that are provided in NEW_TOKEN frames (see {{frame-new-token}}) need to be valid for longer, but SHOULD NOT be accepted multiple times in a short period.  Servers are encouraged to allow tokens to be used only once, if possible.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-446477111

---

From: Christian Huitema <[email-masked]>
Date: Tue, 11 Dec 2018 23:36:27 -0800

@martinthomson Works for me. 

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-446490844

---

From: MikkelFJ <[email-masked]>
Date: Wed, 12 Dec 2018 02:00:13 -0800

At what point is a token accepted? If  a connection attempt fails halfway and client makes a new connection attempt with the same token, the only token it has, what happens then?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-446530112

---

From: Dmitri Tikhonov <[email-masked]>
Date: Wed, 12 Dec 2018 05:39:11 -0800

@mikkelfj, perhaps the server generates another token and returns it in a new Retry packet?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-446590733

---

From: Martin Thomson <[email-masked]>
Date: Wed, 12 Dec 2018 14:50:09 -0800

@martinthomson pushed 1 commit.

47ae3036136a89b408942f357ed5b68da7eb35ed  Split recommendation for NEW_TOKEN/Retry

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064/files/dbe4f5dca11b71570e72c507f1f649298ef95392..47ae3036136a89b408942f357ed5b68da7eb35ed

---

From: janaiyengar <[email-masked]>
Date: Wed, 12 Dec 2018 18:20:25 -0800

janaiyengar approved this pull request.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#pullrequestreview-184478941

---

From: janaiyengar <[email-masked]>
Date: Wed, 12 Dec 2018 18:21:01 -0800

I'd like to merge this. Anyone opposed?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-446818389

---

From: ianswett <[email-masked]>
Date: Wed, 12 Dec 2018 18:48:58 -0800

ianswett approved this pull request.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#pullrequestreview-184483719

---

From: Kazuho Oku <[email-masked]>
Date: Wed, 12 Dec 2018 19:14:24 -0800

kazuho approved this pull request.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#pullrequestreview-184487804

---

From: Martin Thomson <[email-masked]>
Date: Wed, 12 Dec 2018 20:02:27 -0800

Merged #2064 into master.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#event-2023224020

---

From: MikkelFJ <[email-masked]>
Date: Thu, 13 Dec 2018 00:57:00 -0800

@dtikhonov 

>@mikkelfj, perhaps the server generates another token and returns it in a new Retry packet?

Retry can only be done once AFAIR

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-446890761

---

From: Christian Huitema <[email-masked]>
Date: Thu, 13 Dec 2018 20:43:13 +0000 (UTC)

@mikkelfj : _"If a connection attempt fails halfway and client makes a new connection attempt with the same token, the only token it has, what happens then?"_  

The token is logically tied to the original CID. It is only valid in the context of that original connection. The client can repeat the second (retry) Initial packet, but it cannot reuse the token in a new connection attempt with a new CID. If the connection fails, the new attempt will have to start from scratch.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-447113938