Search code examples
phpnginxopenssltls1.3

$ssl_early_data from nginx: should the application use it somehow?


I'm preparing to turn on nginx ssl_early_data to enable RTT-0 with TLS 1.3.

I understand that, if I don't do it right, replay attacks become possible. I understand that, to prevent this, you need to also use $ssl_early_data

Requests sent within early data are subject to replay attacks. To protect against such attacks at the application layer, the $ssl_early_data variable should be used.

What I don't understand is if it's enough to put this directive in the nginx configuration or if/how the PHP application on my server should somehow use this $ssl_early_data variable and do some additional checks.


Solution

  • You are correct that this header itself doesn't do anything, you need additional logic in your PHP application.

    In my case I'm using a fastcgi variable rather than a header:

    fastcgi_param  TLS_EARLY_DATA     $ssl_early_data;
    

    Then in PHP you need to perform a check for any request that is at risk for a replay attack:

    if ($_SERVER['TLS_EARLY_DATA'] === '1') {
        http_response_code(425);
        exit;
    }
    

    You need this sort of check on everything you want Replay protection on (eg. POST /transfer_money).

    While you can leave it off of something that has no side effects (eg. GET /account_balance).

    Because the attacker cannot decode the payload in the replay, the GET has no teeth and you can allow those requests to use TLS Early Data.


    Finally, most browsers do not yet have support for a HTTP 425 Too Early so I would strongly recommend returning an error page telling them to "Refresh and resubmit" the form.

    As browser support improves, fewer people will see that error page and browsers will handle 425 errors transparently, but we are not there yet.

    "425 Too Early" is currently supported in:

    • Firefox 58+

    And you can track other browsers here: