Skip to content

device: do not update peer endpoint on cookie replies - #497

Open
miguelcorderopamphile wants to merge 1 commit into
cloudflare:masterfrom
miguelcorderopamphile:fix/cookie-reply-endpoint-update
Open

miguelcorderopamphile wants to merge 1 commit into
cloudflare:masterfrom
miguelcorderopamphile:fix/cookie-reply-endpoint-update

Conversation

@miguelcorderopamphile

Copy link
Copy Markdown

Fixes #496.

What

The device UDP handler updated the peer endpoint (roaming) and created a connected socket based on the source address of any packet that did not return an error, including cookie replies. Cookie replies are not authenticated peer traffic (the cookie is encrypted with a key derived from public values and its AAD is the mac1 of an observed handshake), so an on-path attacker could forge or replay one from an arbitrary address and redirect all of the peer traffic (handshakes, keepalives, data) to that address.

This PR only updates the endpoint / creates the connected socket for authenticated traffic.

Why

Parity with wireguard-go and the Linux kernel; Mullvad gotatun removed the same behavior for the same reason ("Do not update peer endpoint/roam on received cookie replies. This change is made to be consistent with Linux kernel and wireguard-go").

Verification

  • cargo test -p boringtun --lib: 10 passed.
  • Live PoC against the daemon (release build):
    • Before: a forged cookie reply sent from a different address replaced endpoint=127.0.0.1:51999 with the attacker address (endpoint=127.0.0.2:55505) and the next handshake init went to the attacker.
    • After: the endpoint stays 127.0.0.1:51999 and traffic keeps flowing to the configured peer.

Note: the behavior is exercised through the device event loop, so the live PoC (raw UDP packets) was used instead of a unit test; happy to add an integration test under device/integration_tests if you prefer.

Cookie replies are not authenticated peer traffic: the cookie is encrypted
with a key derived from public values and its AAD is the mac1 of an observed
handshake, so an on-path attacker can forge or replay them from any source.
The device loop currently updates the peer endpoint (roaming) and creates a
connected socket based on the source address of any packet that did not
error, including cookie replies. A single forged cookie reply therefore
redirects all of the peer's subsequent traffic to an arbitrary address
(persistent tunnel blackhole).

Only update the endpoint and create the connected socket for authenticated
traffic. Parity with wireguard-go and the Linux kernel; Mullvad's gotatun
removed this behavior for the same reason.

Verified with a live PoC against the daemon: before the change a forged
cookie reply sent from a different address replaced endpoint=127.0.0.1:51999
with the attacker address and redirected the client handshake traffic; after
the change the endpoint is unchanged and traffic keeps flowing to the
configured peer.

Signed-off-by: Miguel Cordero Pamphile <miguelcorderopamphile@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

device: forged cookie replies update the peer endpoint (traffic redirection / persistent blackhole)

1 participant