Cách HTTP/3 và QUIC fingerprinting hoạt động: các tham số truyền tải trong gói QUIC Initial, tín hiệu ALPN h3, và khác biệt so với HTTP/2 fingerprinting.
HTTP/2 fingerprinting đọc khung SETTINGS, mức tăng cửa sổ và thứ tự pseudo-header mà client gửi qua TCP+TLS. HTTP/3 gộp toàn bộ bắt tay đó vào một transport dựa trên UDP duy nhất — QUIC — và trong quá trình đó, một số tín hiệu chuyển sang vị trí mới, một số khác được sáp nhập vào tầng TLS, và một tín hiệu biến mất hoàn toàn. Kết quả là một dấu vân tay chồng lấn với TLS fingerprinting nhiều hơn so với HTTP/2, nhưng không hoàn toàn giống nó.
Điểm mấu chốt
- QUIC gộp bắt tay transport và TLS thành một round trip. Gói UDP đầu tiên mà client QUIC gửi — gói Initial — mang theo TLS 1.3 ClientHello, vì vậy mọi thứ mà JA3/JA4 đọc từ ClientHello qua TCP đều có mặt ở đây.
- Tham số truyền tải QUIC là một tín hiệu mới, đặc thù cho giao thức. Chúng được gửi kèm trong ClientHello dưới dạng tiện ích mở rộng TLS
quic_transport_parameters(RFC 9001) và tiết lộ các giá trị đặc thù triển khai — như giới hạn kiểm soát luồng ban đầu và độ dài connection ID — mà HTTP/2 không có tương đương. - JA4 đã hỗ trợ QUIC sẵn. Ký tự đầu tiên của dấu vân tay ghi lại transport quan sát được:
qcho QUIC,tcho TCP,dcho DTLS — xem đặc tả JA4. Dấu vân tay dạngq13d...có thể so sánh trực tiếp vớit13d...từ cùng client qua TCP. - Khung SETTINGS riêng của HTTP/3 mỏng hơn nhiều so với HTTP/2, và các khung PRIORITY đã biến mất — thay bằng lược đồ Extensible Priorities dựa trên header, mà hầu hết client không hề gửi.
- Giá trị ALPN
h3là tín hiệu tầng ứng dụng sớm nhất: nó xuất hiện trong cùng tiện ích mở rộng ClientHello nhưh2từng làm cho HTTP/2, chỉ khác là được mang qua QUIC thay vì TCP.
Tại sao QUIC thay đổi bức tranh fingerprinting
HTTP/2 fingerprinting tồn tại vì TCP và TLS là hai giao thức tách biệt: bắt tay TCP thiết lập kết nối, rồi ClientHello TLS đàm phán mã hóa, rồi — sau khi TLS xong — client mới gửi các khung khởi động riêng của HTTP/2 (SETTINGS, WINDOW_UPDATE, PRIORITY). Ba tầng, ba cơ hội lấy dấu vân tay.
QUIC (RFC 9000) là một transport dựa trên UDP gộp việc thiết lập kết nối và mã hóa vào một lần trao đổi. Gói đầu tiên của nó — gói Initial — mang theo một ClientHello TLS 1.3 đầy đủ bên trong khung CRYPTO, được tích hợp thẳng vào bắt tay transport (RFC 9001) thay vì xếp chồng lên trên như trước. HTTP/3 (RFC 9114) sau đó chạy trên một kết nối QUIC đã được thiết lập sẵn, tái sử dụng phần lớn những gì bản thân QUIC đã cung cấp — ghép kênh luồng và kiểm soát luồng — thay vì phải định nghĩa lại chúng như HTTP/2 đã làm cho TCP.
Việc tái cấu trúc này có nghĩa là client QUIC để lộ:
- Một ClientHello TLS 1.3, được gửi bên trong gói Initial — cùng bộ mã hóa, tiện ích mở rộng và giá trị ALPN mà JA3/JA4 đã lấy dấu vân tay qua TCP.
- Tham số truyền tải QUIC, một tiện ích mở rộng TLS mới chỉ có ở bắt tay này.
- Một khung SETTINGS HTTP/3 nhỏ hơn nhiều, được gửi trên một luồng điều khiển một chiều sau khi kết nối đã thiết lập xong.
Tham số truyền tải QUIC: tín hiệu mới
Mọi client QUIC đều phải gửi tiện ích mở rộng quic_transport_parameters (mã điểm 0x39) trong ClientHello của nó, khai báo các giá trị như initial_max_data, initial_max_stream_data, max_idle_timeout và active_connection_id_limit. Các tham số này mô tả giới hạn kết nối mà client sẵn sàng hỗ trợ — và, giống như giá trị SETTINGS của HTTP/2, các giá trị mặc định cụ thể mà một triển khai chọn khác nhau giữa các thư viện QUIC.
Stack QUIC của Chrome, neqo của Firefox, quiche (dùng bởi curl và Cloudflare), msquic và ngtcp2 mỗi cái đều có tham số truyền tải mặc định khác nhau. Vì tiện ích mở rộng này nằm trong cùng ClientHello mà JA3/JA4 đã băm, một server làm fingerprinting không cần cơ chế thu thập riêng — nó chỉ cần phân tích thêm tiện ích mở rộng bổ sung này từ gói tin nó đã đang đọc.
JA4 đã nói được ngôn ngữ QUIC
TLS fingerprinting không cần một thuật toán mới cho QUIC — nó chỉ cần thêm một trường. Đặc tả JA4 mã hóa transport quan sát được thành ký tự đầu tiên của dấu vân tay: q cho QUIC, d cho DTLS, t cho TLS thông thường qua TCP. Mọi thứ sau ký tự đó — phiên bản TLS, hash cipher và hash tiện ích mở rộng — được tính theo đúng cùng một cách bất kể transport, vì nó vẫn đang đọc cùng một cấu trúc ClientHello.
Điều này có một hệ quả thực tế: một server đã kiểm tra JA4 cho TLS fingerprinting không cần logic mới nào để lấy dấu vân tay các kết nối QUIC. Nó tự động nhận được một dấu vân tay kiểu q13d..., và có thể so sánh trực tiếp với dấu vân tay t13d... mà cùng trình duyệt đó tạo ra qua TLS thông thường — sự không khớp ở phần đã băm giữa dấu vân tay TCP và QUIC của cùng một client tự nó là tín hiệu đáng điều tra.
Khung SETTINGS mỏng hơn của HTTP/3
Khung SETTINGS riêng của HTTP/3 (RFC 9114 §7.2.4) chỉ định nghĩa SETTINGS_MAX_FIELD_SECTION_SIZE ở tầng HTTP. Hai tham số nữa — SETTINGS_QPACK_MAX_TABLE_CAPACITY và SETTINGS_QPACK_BLOCKED_STREAMS — đến từ QPACK, lược đồ nén field của HTTP/3 (một thiết kế lại HPACK của HTTP/2 để phù hợp với việc gửi không theo thứ tự), được định nghĩa riêng. So với sáu tham số SETTINGS chuẩn của HTTP/2 cộng thêm một khung WINDOW_UPDATE, đây là một bề mặt nhỏ hơn nhiều: bản thân QUIC đã xử lý kiểm soát luồng và giới hạn luồng ở tầng transport thông qua các tham số truyền tải nói trên, nên HTTP/3 không cần đàm phán lại chúng ở tầng ứng dụng như HTTP/2 từng phải làm qua TCP thuần.
Không còn khung PRIORITY
Các khung PRIORITY của HTTP/2 — vốn đã bị loại bỏ bởi RFC 9113 — không có bất kỳ tương đương nào trong bộ khung cốt lõi của HTTP/3. Việc ưu tiên luồng thay vào đó chuyển sang Extensible Priorities, một lược đồ báo hiệu mức độ khẩn cấp qua trường header Priority của HTTP (hoặc khung tương đương) thay vì một khung nhị phân riêng ngay từ đầu kết nối. Nhiều client không hề gửi tín hiệu ưu tiên rõ ràng, mà dựa vào mặc định của server — điều này loại bỏ thứ từng là một trong những trường đặc trưng nhất của các nghiên cứu fingerprinting HTTP/2 thời kỳ đầu.
Khác biệt so với HTTP/2 fingerprinting
| Tín hiệu | HTTP/2 (qua TCP+TLS) | HTTP/3 (qua QUIC) |
|---|---|---|
| ClientHello TLS | Bắt tay TCP + TLS riêng biệt | Nhúng trong gói QUIC Initial |
| Tham số tầng transport | Không có (TCP không có tương đương) | Tiện ích mở rộng quic_transport_parameters |
| Khung SETTINGS | 6 tham số chuẩn | 1 tham số HTTP + 2 tham số QPACK |
| Ưu tiên luồng | Khung PRIORITY (đã loại bỏ) | Header Extensible Priorities, thường không được đặt |
| Giá trị ALPN | h2 | h3 |
| Khả năng áp dụng JA3/JA4 | Trực tiếp (TLS qua TCP) | Trực tiếp, kèm ký hiệu transport q |
Kết quả thực tế: HTTP/3 fingerprinting dựa nhiều vào tầng TLS hơn so với HTTP/2 fingerprinting, vì QUIC đã hấp thụ phần lớn những gì từng là các bước đàm phán transport riêng biệt vào cùng ClientHello mà JA3/JA4 đã đọc.
Ứng dụng trong phát hiện bot và VPN
Các hệ thống phát hiện quan tâm đến QUIC fingerprinting vì một lý do cụ thể: một tỷ lệ ngày càng lớn lưu lượng trình duyệt đến Google, các trang sau Cloudflare và các bên sớm áp dụng HTTP/3 khác hiện đến qua QUIC theo mặc định, không phải TCP. Một framework bot xây dựng quanh việc giả mạo bắt tay TLS qua TCP không tạo ra bất kỳ lưu lượng QUIC nào — bản thân điều đó đã mang tính thông tin, vì một instance Chrome thật truy cập một origin hỗ trợ HTTP/3 thường sẽ đàm phán QUIC thay vì rơi về TCP. Ngược lại, các công cụ có nói được QUIC (qua binding quiche hoặc msquic) vẫn mang theo tham số truyền tải mặc định và cài đặt QPACK đặc trưng của thư viện đó — có thể phân biệt với stack không dùng quiche của trình duyệt thật, theo đúng cách một client HTTP/2 giả mạo bị lộ qua giá trị SETTINGS.
Đối với phát hiện VPN và proxy, QUIC tạo ra một điểm khác biệt: vì nó chạy qua UDP, một số tường lửa doanh nghiệp và thiết bị trung gian cũ chặn nó hoàn toàn, buộc client phải rơi về HTTP/2 qua TCP. Mẫu hình rơi-về-TCP đó — một client có User-Agent tự nhận là phiên bản Chrome hỗ trợ QUIC nhưng chưa bao giờ đàm phán h3 — bản thân nó là một tín hiệu quan sát được, tách biệt với nội dung của dấu vân tay.
Các dấu vân tay truyền tải QUIC và TLS mô tả ở đây được quan sát ở phía server, nên chúng không lộ ra cho JavaScript của trang — nhưng chúng phối hợp với các tín hiệu phía client mà hệ thống phát hiện đọc từ trình duyệt của bạn. Bạn có thể tự xem những tín hiệu đó bằng công cụ phát hiện bot của BrowserInsight: nó hiển thị trạng thái navigator.webdriver, các dấu vết headless và tự động hóa, cùng tính nhất quán của dấu vân tay, mỗi mục kèm một giải thích dễ hiểu và toàn bộ được tính toán ở phía client.
Câu hỏi thường gặp
Tôi có cần công cụ mới để xem dấu vân tay QUIC của mình không?
Về mặt khái niệm thì không — bất kỳ triển khai JA4 phía server nào cũng đã tạo ra nó, vì ClientHello của QUIC được phân tích giống hệt như trong TLS qua TCP. Điều thay đổi là nơi việc bắt gói tin diễn ra: QUIC đến qua UDP, nên một server hoặc thiết bị trung gian chỉ được xây dựng để soi luồng TCP sẽ không thấy nó nếu không bắt UDP riêng.
Bot có thể tránh QUIC fingerprinting bằng cách từ chối dùng HTTP/3 không?
Chỉ một phần, và đó là đánh đổi tín hiệu này lấy tín hiệu khác. Rơi về HTTP/2 tránh được fingerprinting đặc thù của QUIC, nhưng một trình duyệt hiện đại thật truy cập trang hỗ trợ HTTP/3 thường sẽ đàm phán QUIC — vì vậy một client liên tục né tránh nó trong khi tự nhận là Chrome hay Firefox phiên bản mới nhất tự nó đã là một bất thường đáng chú ý.
Mã hóa bắt tay QUIC như ECH có che giấu các tín hiệu này không?
Encrypted Client Hello che giấu các trường nhạy cảm của ClientHello bên trong (như SNI) khỏi người quan sát mạng, nhưng server đích — nơi giải mã bắt tay để phục vụ kết nối — vẫn thấy đầy đủ ClientHello, tham số truyền tải và SETTINGS của HTTP/3. ECH thay đổi những gì một người quan sát mạng thụ động giữa client và server có thể thấy; nó không thay đổi những gì bản thân server gốc có thể lấy dấu vân tay.
HTTP/3 fingerprinting đã trưởng thành như HTTP/2 fingerprinting chưa?
Chưa bằng, chủ yếu vì việc áp dụng QUIC, dù đáng kể ở một số nhà vận hành lớn, vẫn nhỏ hơn TCP+TLS phổ biến khắp nơi. Khi ngày càng nhiều origin và CDN kết thúc HTTP/3 theo mặc định, có thể kỳ vọng fingerprinting nhận biết QUIC sẽ trở thành một phần tiêu chuẩn của các stack phát hiện bot, giống như JA3/JA4 và dấu vân tay Akamai đã trở thành.


