tls_inspector: fix GREASE filtering in JA4_c signature algorithms - #46658
Open
dangle1 wants to merge 1 commit into
Open
tls_inspector: fix GREASE filtering in JA4_c signature algorithms#46658dangle1 wants to merge 1 commit into
dangle1 wants to merge 1 commit into
Conversation
The JA4 fingerprint's third component hashes the ClientHello's extension list joined to its signature_algorithms list. Per the JA4 spec, GREASE codepoints must be excluded everywhere they appear -- including in signature_algorithms. `getJA4ExtensionHash` already applies `isNotGrease` to extension type IDs, and `getJA4CipherHash`, `countCiphers`, and `countExtensions` apply it to their respective inputs. The signature_algorithms collection loop was the sole exception, pushing every 16-bit codepoint from the extension body unconditionally. Clients that inject a GREASE value into signature_algorithms (e.g. Chrome's per-handshake random GREASE selection) therefore produce a different JA4_c hash per connection while all other parts of the fingerprint are identical -- resulting in many-to-one hash collapse when compared to spec-compliant implementations. Guard the `sig_algs.push_back` call with `isNotGrease(sig_alg)`, matching the treatment already applied elsewhere in the file. Adds a regression test that asserts JA4 fingerprint equality between two ClientHellos that differ only in the presence of a GREASE codepoint in signature_algorithms. Spec reference: https://github.com/FoxIO-LLC/ja4/blob/main/technical_details/JA4.md Note: this change was drafted with AI assistance and reviewed by the author. Signed-off-by: dangle <dangle@pinterest.com>
dangle1
requested a deployment
to
external-contributors
August 11, 2026 22:04 — with
GitHub Actions
Waiting
|
Hi @dangle1, welcome and thank you for your contribution. We will try to review your Pull Request as quickly as possible. In the meantime, please take a look at the contribution guidelines if you have not done so already. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The JA4 fingerprint's third component hashes the ClientHello's extension list joined to its
signature_algorithmslist. Per the JA4 spec, GREASE codepoints must be excluded everywhere they appear — including insignature_algorithms.getJA4ExtensionHashalready appliesisNotGreaseto extension type IDs, andgetJA4CipherHash,countCiphers, andcountExtensionsapply it to their respective inputs. Thesignature_algorithmscollection loop was the sole exception, pushing every 16-bit codepoint from the extension body unconditionally.Clients that inject a GREASE value into
signature_algorithms(e.g. Chrome's per-handshake random GREASE selection, drawn from the 16 reserved code points0x0a0a,0x1a1a, …,0xfafa) therefore produce a different JA4_c hash per connection while all other parts of the fingerprint are identical — resulting in many-to-one hash collapse when compared against spec-compliant implementations.Fix
Guard the
sig_algs.push_back(sig_alg)call ingetJA4ExtensionHashwithisNotGrease(sig_alg), matching the treatment already applied everywhere else in the file.Test plan
TEST(JA4Fingerprinter, GreaseValueFilteredFromSignatureAlgorithms)inja4_fingerprint_test.ccthat constructs two `SSL_CLIENT_HELLO`s identical except for a GREASE codepoint (`0x0a0a`) in `signature_algorithms` and asserts `JA4Fingerprinter::create` produces the same fingerprint for both.Notes