By May 2025, HTTP/3 traffic accounted for nearly 35% of all internet traffic. With this rapid adoption, the question naturally arises: can HTTP/3 traffic be fingerprinted in the same way as HTTP/2?
The short answer is yes.
Revisiting HTTP/2 Fingerprints
Fingerprinting in HTTP/2 is well-established. For example, opening https://tls.browserleaks.com/json with Chrome 136 shows the following akamai_text field:
{
"akamai_text": "1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p"
}
This string is divided into four parts, each corresponding to an HTTP/2 feature:
-
Settings – e.g.,
1:65536;2:0;4:6291456;6:262144. Representing values from the HTTP/2 settings frame. -
Window Update – the value of the
window_updateframe. -
Weight – now deprecated, so browsers typically send
0. -
Pseudo Headers – HTTP/2 defines pseudo-header fields such as
:method,:path, etc., and their order varies across clients.
By combining these values, it is straightforward to distinguish a request from a legitimate browser versus an automated script, such as curl or requests.
Examples of browser fingerprints:
Chrome 136: 1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p
Firefox 138: 1:65536;2:0;4:131072;5:16384|12517377|0|m,p,a,s
Safari 18.4: 2:0;3:100;4:2097152;9:1|10420225|0|m,s,a,p
Defining HTTP/3 Fingerprints
HTTP/3 adopts a similar design, with QUIC replacing TCP as the transport layer. This allows for comparable fingerprinting strategies.
Using Wireshark, we can observe the settings frame for different clients:
curl includes MaxFieldSection, MaxTableCapacity, and BlockedStream.
Firefox includes MaxTableCapacity, BlockedStream, and EnableWebTransport.
Chrome follows its tradition of adding a GREASE field (random, undefined values) to enforce forward compatibility.
What Is GREASE?
GREASE (Generate Random Extensions And Sustain Extensibility) is a mechanism where clients insert undefined, random fields. This ensures servers remain compatible with potential future extensions.
The “Perk” Fingerprint
Similar to HTTP/2, we can define an HTTP/3 fingerprint. We propose the perk fingerprint, based on two key components:
- Settings – same format as HTTP/2 but with HTTP/3-specific keys and values.
- Pseudo Headers – identical rules to HTTP/2 for pseudo-header order.
The structure:
perk_text := SETTINGS|PSEUDO_HEADERS
perk_hash := md5(perk_text)
Examples
- curl:
settings = 6:4611686018427387903;1:0;7:0
pseudo_headers = mpsa
perk_text = 6:4611686018427387903;1:0;7:0|mpsa
perk_hash = cb11122dd57d03bad5d061c9abe83ddd
- firefox:
settings = 1:65536;7:20;727725890:0
pseudo_headers = mpas
perk_text = 1:65536;7:20;727725890:0|mpas
perk_hash = 2e09f470459efcf3c9354e402a54208d
- chrome (with GREASE):
settings = 1:65536;6:262144;7:100;51:1;GREASE
pseudo_headers = masp
perk_text = 1:65536;6:262144;7:100;51:1;GREASE|masp
perk_hash = 51da7e5a519bbb4b6943e603907816eb
Conclusion
HTTP/3 traffic can indeed be fingerprinted, just like HTTP/2.
For convenience, we created a simple API where you can check your client’s HTTP/3 fingerprint:
👉 https://fp.impersonate.pro/api/http3
Coming Next
You might wonder:
- Can HTTP/3 traffic be proxied?
- Can fingerprints be modified?
- What do the TLS fingerprints look like in HTTP/3?
Stay tuned for the next article.



Top comments (0)