HTTP/2 for Apache httpd
One of the less glamorous bits of the HTTP/2 protocol is padding. And
with v1.14.1 of mod_h2
you can configure it. But what for? And what
does it do, exactly?
Padding is a crypto graphic technique for obscuring message lengths.
A simple example is someone sending you an answer, encrypted, of 'Yes' or 'No'. A listener, knowing it is one of the two, does not need to decrypt the response, just look at the length of it. With padding, one can make both answers have the same length, preventing this sort of attack.
In real life, however, fixed length padding is not secure. For security purposes alone, one could make any answer from a web server 1 terra byte long, using padding. But this is for performance and usability reasons not practical. Real life protocols have to compromise.
In HTTP/2, the range for padding a packet of data - a frame - is 0-255 bytes. Padding all frames to the same length is therefore not possible. The best one could possibly do by fixed length padding is to make all small frames 256 bytes long, a bit longer ones 512, even longer ones 768, etc. Or smaller steps, for example multiples of 16. In any case, there would be a threshold of payload length, where the observable frame length switches from on number to the next. This can, again, be exploited by an attacker.
Coming back to our example: if the message to secure is of the form:
"Dear $USER, my answer is $ANSWER!"
, an attacker would just use
different user names of varying length to find out when the frame length switches.
By observing many messages this way, an attacker will learn which user name
length will make the frame length change with the answer.
You can check the visibility of answer lengths by installing wireshark
and looking at HTTP/2 traffic. I did this by invoking curl
and nghttp
from the command line against a local Apache. I was calling a simple python script that echos
the request data back. When I sent 'x', the server sent back one TLS frame with 95 bytes. When
sending 'xx', it sent a frame with 96 bytes. On 'xxx', it had one with 97. This happens in TLS 1.2,
as well as in the new 1.3.
This is not always the case. When the server has enough frames to send, it will wrap several of them into a single TLS frame. h2 frame sizes will then not be visible. But an intermediate could just delay frames send from you to the server, so the server has less to respond with and is more likely to send one h2 frame inside one TLS frame.
The way to make limited padding work is to randomize the amount of padding. Using a pseudo random number generator, each frame gets 0-N bytes of padding. The higher the N, the better protected the message lengths are. The downside is traffic overhead, of course. The quality of the random number generator plays of course also a vital role here, as well as the timing or CPU usage information leaked etc. that might give a hint how many padding bytes were used.
The take away here is that padding makes messages more secure than not padding, but it is difficult to assess how much more secure. In case of HTTP/2, where message lengths are easily observable, adding random padding seems to be an easy improvement.
The mod-h2
configuration directive, available since v1.14.1, is
H2Padding
. It takes the form:
H2Padding Nwhere
N
is a number in the range 0-8. You may specify that
globally or for each virtual host. The default setting is 0 - to keep the
behaviour of previous versions - for now.
N
determines the number of bits of applicable padding length.
0
applies no padding, 2
gives 0-3 padding bytes,
8 allows the full range of 0-255.
This is still an area of experimentation. I am tempted
to make the default anything else but 0. Secure by default is a good design goal.
And then there is the matter of IO size restrictions (see configuration
directive H2TLSWarmUpSize
). Should they apply a limit to padding or
be shredded by it?
Feedback appreciated.
Thanks!
Münster, 05.03.2019,
Stefan Eissing, greenbytes GmbH
Copyright (C) 2019 greenbytes GmbH
Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. See LICENSE for details.