Make WordPress Core

Opened 10 months ago

Closed 4 months ago

Last modified 3 months ago

#58769 closed defect (bug) (wontfix)

HTTP/3 Early-Data/0-RTT replay attack

Reported by: kkmuffme's profile kkmuffme Owned by:
Milestone: Priority: normal
Severity: major Version: 6.3
Component: Security Keywords:
Focuses: Cc:

Description

This is a security issue non-specific to WordPress, however WordPress has the reach and responsibility to mitigate common user misconfigurations.
(which is why this is reported in Trac and not in HackerOne)

HTTP/3 support is getting more ubiquitous, but unfortunately a lot of people don't know what they are doing; inadvertetly opening up their WP for replay attacks when "early data" is used.
e.g. with Cloudflare, you just need to change a setting to enable 0-RTT; Cloudflare will correctly forward the Early-Data header to the origin, but the origin (nginx, apache or the application layer like WP) usually miss the required handling for that.

To allow using 0-RTT with WP safely*, I propose:
1) as early as possible (to avoid performance penalties): if the $_SERVER['REQUEST_METHOD'] !== 'GET' and isset( $_SEVER['HTTP_EARLY_DATA'] ) && $_SEVER['HTTP_EARLY_DATA'] === '1', always return status 425 and exit.
We can do that since the the presence of the header indicates that the intermediary knows/supports handling of the 425 status, and will retry the request again without early data.
e.g. Cloudflare already does not allow non-idempotent 0-RTT (e.g. POST) requests in the first place, however with nginx 1.25 that supports HTTP/3 and other CDNs that might not be the case, therefore this makes sense as a first, general security barrier.

2) when validating a nonce and the request method is GET, we need to check for the Early-Data header too. Since using a nonce indicates that this is not an idempotent request, therefore at risk of replay attacks.
In that case, we have 2 options:
a) if headers_sent(), return false, since the nonce verification failed (since it could have been a replay attack)
b) else return status 425 and exit

*safely as in the same safety standard that currently exists with WP nonce (which is vulnerable to certain replay attacks already, since it's not really a number used only once)

Change History (3)

#1 @kkmuffme
10 months ago

EDIT: just found out 0-RTT is enabled by default on Cloudflare, so this is something (especially the nonced GET requests) that need to be addresses rather sooner than later.

#2 @kkmuffme
4 months ago

  • Resolution set to wontfix
  • Status changed from new to closed

This cannot be fixed with the current nonce system, since it does not offer replay protection itself, since nonces can be reused.
Therefore any fixes here are futile, since this bug already exists for regular (non-early) requests with nonces, since they can be replayed easily.

#3 @swissspidy
3 months ago

  • Milestone Awaiting Review deleted
Note: See TracTickets for help on using tickets.