Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document request forgery #3996

Merged
merged 13 commits into from
Sep 8, 2020
216 changes: 215 additions & 1 deletion draft-ietf-quic-transport.md
Original file line number Diff line number Diff line change
Expand Up @@ -2577,7 +2577,10 @@ discontinue use of the old server address. If path validation fails, the client
MUST continue sending all future packets to the server's original IP address.


### Responding to Connection Migration
### Migration to a Preferred Address

A client that migrates to a preferred address MUST validate the address it
chooses before migrating; see {{forgery-spa}}.

A server might receive a packet addressed to its preferred IP address at any
time after it accepts a connection. If this packet contains a PATH_CHALLENGE
Expand Down Expand Up @@ -6357,6 +6360,217 @@ this behavior. An endpoint can then immediately close the connection with a
connection error of type PROTOCOL_VIOLATION; see {{immediate-close}}.


## Request Forgery Attacks

A request forgery attack occurs where an endpoint causes its peer to issue a
request towards a victim, with the request controlled by the endpoint. Request
forgery attacks aim to provide an attacker with access to capabilities of its
peer that might otherwise be unavailable to the attacker. For a networking
protocol, a request forgery attack is often used to exploit any implicit
authorization conferred on the peer by the victim due to the peer's location in
the network.

For request forgery to be effective, an attacker needs to be able to influence
what packets the peer sends and where these packets are sent. If an attacker
can target a vulnerable service with a controlled payload, that service might
perform actions that are attributed to the attacker's peer, but decided by the
attacker.

For example, cross-site request forgery {{?CSRF=DOI.10.1145/1455770.1455782}}
exploits on the Web cause a client to issue requests that include authorization
cookies {{?COOKIE=RFC6265}}, allowing one site access to information and
actions that are intended to be restricted to a different site.
janaiyengar marked this conversation as resolved.
Show resolved Hide resolved

As QUIC runs over UDP, the primary attack modality of concern is one where an
janaiyengar marked this conversation as resolved.
Show resolved Hide resolved
attacker can select the address to which its peer sends UDP datagrams and can
control some of the unprotected content of those packets. As much of the data
sent by QUIC endpoints is protected, this includes control over ciphertext. An
attack is successful if an attacker can cause a peer to send a UDP datagram to
a host that will perform some action based on content in the datagram.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add a paragraph here that provides examples of real harm? What protocols are both UDP-based and non-authenticated in a way that would make them vulnerable to a request forgery from a QUIC stack?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have anything concrete. Any example would be hard to describe with anything other than "this person/organization did something really unwise". Given the absence of a news-worthy example that would be easy to reference, this is really just a request to search for someone to shame.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not trying to shame anyone. I'm trying to ascertain whether this change is the right one: we're worsening the performance of the protocol (by requiring extra round-trips in some scenarios) and if the attack is purely theoretical then we shouldn't do that. Having a concrete example of actual harm would help motivate the performance degradation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only place this adds a round trip is for a migration to a preferred address, but that only delays migration, it doesn't prevent the connection from being used.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Message Send Service (RFC 1312) seems like a potential target.

This service is primarily intended for "open" environments:
controlled local area networks used by reasonably trusted
participants, in which security considerations may be relaxed in the
interests of ease of use and administration. In such an environment
it is appropriate to trust the user name and source IP address as
identifying the actual sender of the message.


This section discusses ways in which QUIC might be used for request forgery
attacks.

This section also describes limited countermeasures that can be implemented by
QUIC endpoints. These mitigations can be employed unilaterally by a QUIC
implementation or deployment, without potential targets for request forgery
attacks taking action. However these countermeasures could be insufficient if
UDP-based services do not properly authorize requests.


### Control Options for Endpoints

QUIC offers some opportunities for an attacker to influence or control where
its peer sends UDP datagrams:

* initial connection establishment ({{handshake}}), where a server is able to
MikeBishop marked this conversation as resolved.
Show resolved Hide resolved
choose where a client sends datagrams, for example by populating DNS records;

* preferred addresses ({{preferred-address}}), where a server is able to choose
where a client sends datagrams; and

* spoofed connection migrations ({{address-spoofing}}), where a client is able
to use source address spoofing to select where a server sends subsequent
datagrams.

In all three cases, the attacker can cause its peer to send datagrams to a
victim that might not understand QUIC. That is, these packets are sent by
the peer prior to address validation; see {{address-validation}}.

Outside of the encrypted portion of packets, QUIC offers an endpoint several
options for controlling the content of UDP datagrams that its peer sends. The
Destination Connection ID field offers direct control over bytes that appear
early in packets sent by the peer; see {{connection-id}}. The Token field in
Initial packets offers a server control over other bytes of Initial packets;
see {{packet-initial}}.

There are no measures in this version of QUIC to prevent indirect control over
the encrypted portions of packets. It is necessary to assume that endpoints are
able to control the contents of frames that a peer sends, especially those
frames that convey application data, such as STREAM frames. Though this depends
to some degree on details of the application protocol, some control is possible
in many protocol usage contexts. As the attacker has access to packet
protection keys, they are likely to be capable of predicting how a peer will
encrypt future packets. Successful control over datagram content then only
requires that the attacker be able to predict the packet number and placement
of frames in packets with some amount of reliability.

This section assumes that limiting control over datagram content is not
feasible. The focus of the mitigations in subsequent sections is on limiting
janaiyengar marked this conversation as resolved.
Show resolved Hide resolved
the ways in which datagrams that are sent prior to address validation can be
used for request forgery.


### Request Forgery with Client Initial Packets

An attacker acting as a server can choose the IP address and port on which it
advertises its availability, so Initial packets from clients are assumed to be
available for use in this sort of attack. The address validation implicit in
the handshake ensures that - for a new connection - a client will not send
other types of packet to a destination that does not understand QUIC or is not
willing to accept a QUIC connection.

Initial packet protection (Section 5.2 of {{QUIC-TLS}}) makes it difficult for
servers to control the content of Initial packets sent by clients. A client
choosing an unpredictable Destination Connection ID ensures that servers are
unable to control any of the encrypted portion of Initial packets from clients.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe that this is correct as written if there is a Retry because the server gets to control the next DCID. I don't think that this is relevant because you would need a round trip to make it work (I think!) but...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is mentioned in the last paragraph of this section. Perhaps we just need to reference that here?


However, the Token field is open to server control and does allow a server to
use clients to mount request forgery attacks. Use of tokens provided with the
NEW_TOKEN frame ({{validate-future}}) offers the only option for request
forgery during connection establishment.

Clients however are not obligated to use the NEW_TOKEN frame. Request forgery
attacks that rely on the Token field can be avoided if clients send an empty
Token field when the server address has changed from when the NEW_TOKEN frame
was received.

Therefore, clients SHOULD NOT send a token received in a NEW_TOKEN frame from
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, the NEW_TOKEN frame is not received from a server in an Initial packet, correct? The first few times I read this, I though that was what you intended.

Assuming I'm now reading this correctly, this SHOULD NOT would seem to be very restrictive for domains which use DNS to load balance traffic. Previously, I assumed that NEW_TOKEN would be used whenever hostnames matched. Am I understanding correctly?

If we're going to add this normative restriction, I would suggest placing the restriction in the section on address validation/etc and then referencing this section.

one server address in an Initial packet that is sent to a different server
address. As strict equality might reduce the utility of this mechanism, clients
MAY employ heuristics that result in different server addresses being treated
as equivalent, such as treating addresses with a shared prefix of sufficient
length as being functionally equivalent (for instance, /24 in IPv4 or /56 in
IPv6). In addition, clients SHOULD treat a preferred address that is
successfully validated as equivalent to the address on which the connection was
made; see {{preferred-address}}.

Sending a Retry packet ({{packet-retry}}) offers a server the option to change
the Token field. After sending a Retry, the server can also control the
Destination Connection ID field of subsequent Initial packets from the client.
This also might allow indirect control over the encrypted content of Initial
packets. However, the exchange of a Retry packet validates the server's
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have text that explicitly mandates that replies to a RETRY packet MUST be sent to the same address?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The design of QUIC relies on endpoints retaining a stable address for the duration of the handshake. An endpoint MUST NOT initiate connection migration before the handshake is confirmed, as defined in section 4.1.2 of [QUIC-TLS].

Not sure if that is enough, as this is not directly a requirement, but more of an assumption.

address, thereby preventing the use of subsequent Initial packets for request
forgery.


### Request Forgery with Preferred Addresses {#forgery-spa}

Servers can specify a preferred address, which clients then migrate to after
confirming the handshake; see {{preferred-address}}. The Destination Connection
ID field of packets that the client sends to a preferred address can be used
for request forgery.

A client MUST NOT send non-probing frames to a preferred address prior to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing this normative requirement in Security Considerations makes me uneasy as an implementer might miss it. Could we instead move the MUST NOT to the section that defines preferred_address and then only reference it here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that repetition will do.

validating that address; see {{address-validation}}. This greatly reduces the
options that a server has to control the encrypted portion of datagrams.

This document does not offer any additional countermeasures that are specific
to use of preferred addresses and can be implemented by endpoints. The generic
measures described in {{forgery-generic}} could be used as further mitigation.


### Request Forgery with Spoofed Migration

Clients are able to present a spoofed source address as part of an apparent
connection migration to cause a server to send datagrams to that address.

The Destination Connection ID field in any packets that a server subsequently
sends to this spoofed address can be used for request forgery. A client might
also be able to influence the ciphertext.

A server that only sends probing packets ({{probing}}) to an address prior to
address validation provides an attacker with only limited control over the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do find it somewhat ironic that address validation might make this worse: the client sending a PATH_CHALLENGE to the server can pretty much guarantee that the server will send a PATH_RESPONSE with client-provided content to the client's spoofed source address. Should we mention that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered it, but thought that the generic text was enough. Note also that there is no guarantee that PATH_RESPONSE is sent on the same path.

encrypted portion of datagrams. However, particularly for NAT rebinding, this
can adversely affect performance. If the server sends frames carrying
application data, an attacker might be able to control most of the content of
datagrams.

This document does not offer specific countermeasures that can be implemented
by endpoints aside from the generic measures described in {{forgery-generic}}.
However, countermeasures for address spoofing at the network level, in
particular ingress filtering {{?BCP38=RFC2267}}, are especially effective
against attacks that use spoofing and originate from an external network.


### Generic Request Forgery Countermeasures {#forgery-generic}

The most effective defense against request forgery attacks is to modify
vulnerable services to use strong authentication. However, this is not always
something that is within the control of a QUIC deployment. This section
outlines some others steps that QUIC endpoints could take unilaterally. These
additional steps are all discretionary as, depending on circumstances, they
could interfere with or prevent legitimate uses.

Services offered over loopback interfaces (that is, the IPv6 address ::1 or the
IPv4 address 127.0.0.1) often lack proper authentication. Endpoints MAY prevent
connection attempts or migration to a loopback address. Endpoints SHOULD NOT
allow connections or migration to a loopback address if the same service was
previously available at a different interface or if the address was provided by
a service at a non-loopback address. Endpoints that depend on these
capabilities could offer an option to disable these protections.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's nice, but in many scenarios any of the node addresses can be used to reach services local to the node, in the same way as loopback addresses. In server farm scenarios, this requires guessing the local IP of the specific server, but that can probably be done. Same for clients behind NAT.

Copy link
Contributor

@igorlord igorlord Aug 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@huitema This is certainly a way to mount an attack on services that assume that they are serving friendly clients and the network perimeter is secure. It happens, especially when services listen only on RFC1918/unique-local or link-local IPs. It happens even more often with services only listen to loopback and, therefore, think they are immune to any threats coming from outside of the host.

That's why the following is generalizing "non-loopback -> loopback" to “globally routable IP space” -> “RFC1918/unique-local IP space” -> “link-local” -> “loopback”.

Similarly, endpoints could regard a change in address to link-local address
{{?RFC4291}} or an address in a private use range {{?RFC1918}} from a global,
unique-local {{?RFC4193}}, or non-private address as a potential attempt at
request forgery. Endpoints could refuse to use these addresses entirely, but
that carries a significant risk of interfering with legitimate uses. Endpoints
SHOULD NOT refuse to use an address unless they have specific knowledge about
the network indicating that sending datagrams to unvalidated addresses in a
given range is not safe.
MikeBishop marked this conversation as resolved.
Show resolved Hide resolved

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is indeed a valid scenario for client and server discovering that they are behind the same NAT. Wasn't that scenario addressed in Web-RTC using a discovery protocol involving temporary names, in an attempt at privacy?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're referring to draft-ietf-rtcweb-mdns-ice-candidates. For us to do something like that we'd need a way to convey hostnames in preferred_address or elsewhere, and I'm not sure we should be doing that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with David. I don't see any way that the MDNS thing would make sense except in a very narrow domain (which WebRTC is). Nothing stopping someone from defining an extension, of course.

Endpoints MAY choose to reduce the risk of request forgery by not including
values from NEW_TOKEN frames in Initial packets or by only sending probing
frames in packets prior to completing address validation. Note that this does
not prevent an attacker from using the Destination Connection ID field for an
attack.

Endpoints are not expected to have specific information about the location of
servers that could be vulnerable targets of a request forgery attack. However,
it might be possible over time to identify specific UDP ports that are common
targets of attacks or particular patterns in datagrams that are used for
attacks. Endpoints MAY choose to avoid sending datagrams to these ports or not
send datagrams that match these patterns prior to validating the destination
address. Endpoints MAY retire connection IDs containing patterns known to be
problematic without using them.

Note:

: Modifying endpoints to apply these protections is more efficient than
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This depends on what you mean by efficient. Some of the recommendations in this section will add a round-trip which is not efficient.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must be very confused, but your round trip point seems wrong. The key point here is that the round trip is not safe, so any time you attempt that you are exposing services to a potential attack. The point of this text is to describe heuristics that might block attacks without sending a packet at all.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's definitely possible that I'm the one confused. In my understanding, we have two ways of solving the "QUIC endpoint is sending attacker-controlled data to unvalidated address" issue:

  1. the QUIC endpoint limits what it sends before validation
  2. a magical network appliance verifies that the QUIC endpoint isn't sending evil packets where it shouldn't

I do agree with you that we want (1) instead of (2), but saying that (1) is more efficient than (2) isn't necessarily true if you measure efficiency as QUIC performance, because (1) can add a round trip but (2) doesn't

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first requires that the endpoint decide before it sends anything. It can't add a round trip, because that round trip would enable the attack.

deploying network-based protections, as endpoints do not need to perform
any additional processing when sending to an address that has been validated.


## Slowloris Attacks

The attacks commonly known as Slowloris ({{SLOWLORIS}}) try to keep many
Expand Down