mod_h[ttp]2

HTTP/2 for Apache httpd

h2 padding

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.

Fixed Length Padding

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.

Frame Lengths in h2

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.

Random Lengths

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.

H2Padding

The mod-h2 configuration directive, available since v1.14.1, is H2Padding. It takes the form:

H2Padding N
                    
where 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.