quic-go / qpack

a (minimal) QPACK (RFC 9204) implementation in Go
MIT License
29 stars 8 forks source link

use the dynamic table #33

Open marten-seemann opened 10 months ago

marten-seemann commented 10 months ago

The current QPACK implementation only uses the minimal feature set of QPACK (i.e. Huffman-encoding and static table). This guarantees interoperability with other QPACK implementations. However, it's not very efficient, since we'll never be able to compress headers that are sent repeatedly. This is where using the dynamic table would lead to significant savings.

See https://github.com/quic-go/quic-go/issues/2424 for the quic-go tracking issue.

LinZiyuu commented 3 months ago

Hello, I'm looking for an HTTP/3 client that supports QPACK dynamic table compression, quic-go doesn't support dynamic tables right now right?

marten-seemann commented 3 months ago

That's correct. Can you tell us a bit about your use case?

We could add support, but so far we haven't seen a lot of interest.

LinZiyuu commented 3 months ago

We try to test that attacker can exploit QPACK to launch the Denial of Service attack in this senario.(Client<--> CDN/Reverse Proxy <-->Origin)

We think that it works by the client sending an QPACK compressed HTTP requests(dynamic table), then CDN decompressed HTTP requests and forwarding it to Origin.(Client<-Compressed HTTP requests-HTTP/3->CDN<-Decompressed HTTP requests-HTTP/1->Origin)

We have confirmed that attackers can exploit QPACK(static tables) launch the Denial of Service attak. But it have limited amplification factors.

I am a researcher focusing on CDN security and protocol security and will not exploit this vulnerability for malicious attacks. I just want to report this vulnerability to CDN vendors and Reverse Proxy developers after confirming it.

Refer to https://www.ndss-symposium.org/wp-content/uploads/24411-slides.pdf

marten-seemann commented 3 months ago

Refer to https://www.ndss-symposium.org/wp-content/uploads/24411-slides.pdf

Interesting read. I'd expect your attack to work exactly as the HTTP/2 version. For the application, HPACK and QPACK are quite similar. Implementation-wise, QPACK is a lot more complex, since it has to deal with reordering between requests.

LinZiyuu commented 3 months ago

Yes, QPACK is more complicated, so I've searched a lot of QPACK libraries that don't implement dynamic tables. Looking forward that quic-go can support dynamic tables.

DineshAdhi commented 1 month ago

decoding error: no dynamic table

I am trying to decode the headers from a WebTransport Session. Am I getting this because qpack-go doesn't support dynamic table yet?

LinZiyuu commented 1 month ago

You are right. qpack-go doesn't support dynamic table.

marten-seemann commented 1 week ago

decoding error: no dynamic table

I am trying to decode the headers from a WebTransport Session. Am I getting this because qpack-go doesn't support dynamic table yet?

No. qpack dynamic table support is NOT required for establishing a WebTransport session. Dynamic table usage is negotiated via HTTP/3 SETTINGS frames. If peers don't support the dynamic table, encoding will be less efficient, but there's no case where this could lead to a connection failure.

DineshAdhi commented 1 week ago

WebTransport Connection was successful. I was trying to decode the headers that was sent in the Request using the QPACK Decoder. That's when I was getting that error.

So you suggest to disable the Dynamic Table Usage in Settings Frame and everything should work fine?

marten-seemann commented 1 week ago

So you suggest to disable the Dynamic Table Usage in Settings Frame and everything should work fine?

quic-go does the right thing, it doesn't advertise dynamic table support. If you're using a different HTTP/3 implementation with this library, then yes, you need to make sure to not advertise dynamic table support.

DineshAdhi commented 1 week ago

Yes, I am using a custom HTTP/3 implementation. It worked after I disabled the Dynamic Table Support. Thanks a lot.

DineshAdhi commented 1 week ago

@marten-seemann It turns out, the issue was actually due to the setting of N bit at Literal Field Line with Name Reference

When I encode that packet I set the N bit to 1, to ensure that literal string representation is sent across the subsequent hops by the intermediary.

RFC Reference

The condition buf[0]&0x20 > 0 here is triggering the errNoDynamicTable error. But in this case the N bit does not have anything to do with Dynamic table unless you have a reason.

I flipped the 'N' bit to 0 and that solved the issue. PR Reference for the QPACK that I use: PR