Skip to content

Conversation

@arman-bd
Copy link
Owner

  • Added support for multiple Chrome profiles (127-143) with exact JA4 fingerprint matches.
  • Implemented Brotli and zlib decompression for the compress_certificate extension.
  • Updated SSL_CTX configuration to prevent redundant setups for browser profiles.
  • Improved session creation logic to initialize cookie jars and connection pools.
  • Enhanced tests to validate Chrome 143 fingerprint accuracy, including user-agent checks and TLS version support.
  • Updated browser profile aliases to default to Chrome 143.

- Added support for multiple Chrome profiles (127-143) with exact JA4 fingerprint matches.
- Implemented Brotli and zlib decompression for the compress_certificate extension.
- Updated SSL_CTX configuration to prevent redundant setups for browser profiles.
- Improved session creation logic to initialize cookie jars and connection pools.
- Enhanced tests to validate Chrome 143 fingerprint accuracy, including user-agent checks and TLS version support.
- Updated browser profile aliases to default to Chrome 143.
@arman-bd arman-bd self-assigned this Dec 10, 2025
@arman-bd arman-bd changed the title feat: Enhance TLS/HTTP fingerprinting for Chrome 127-143 [FEATURE]: Enhance TLS/HTTP fingerprinting for Chrome 127-143 Dec 10, 2025
@arman-bd arman-bd changed the title [FEATURE]: Enhance TLS/HTTP fingerprinting for Chrome 127-143 [FEATURE] Enhance TLS/HTTP fingerprinting for Chrome 127-143 Dec 10, 2025
- Add brotli dependencies to Linux CI (brotli-devel/libbrotli-dev)
- Add brotli to macOS CI (brew install brotli)
- Add brotli:x64-windows to Windows CI (vcpkg)
- Update setup.py with Windows brotli path detection and linking
- Fix flaky test_simple_get to use local httpbin_server fixture
@codecov-commenter
Copy link

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Homebrew brotli has MACOSX_DEPLOYMENT_TARGET=15.0 which causes
delocate-wheel to fail when building wheels targeting macOS 11.0.

- Add brotli build to scripts/darwin/setup_vendors.sh
- Build with CMAKE_OSX_DEPLOYMENT_TARGET=11.0 for wheel compatibility
- Update setup.py to prefer vendor brotli over Homebrew on macOS
- Remove brotli from brew install in CI (built from source instead)
CMake builds brotli as libbrotlidec.a and libbrotlicommon.a,
not libbrotlidec-static.a and libbrotlicommon-static.a.
Chrome browsers use HTTP/2 by default, so httpmorph should too.
This ensures correct JA4 fingerprint (h2 instead of h1) and
Akamai HTTP/2 fingerprint matching out of the box.
- Add Chrome-like HTTP/2 priority (weight=256, exclusive=1) in http2_logic.c
- Remove zlib from certificate compression, use Brotli only (per Chrome behavior)
- Add Chrome default headers to Session (sec-ch-ua, sec-fetch-*, priority)
- Update all documentation to reflect Chrome 143 as default profile
- Sync README and ReadTheDocs with actual code behavior:
  - Client and Session both default to http2=True
  - Certificate compression is Brotli only
  - Updated fingerprint characteristics (JA4, JA3N, Peetprint, Akamai)
- Fix test names to match http2=True default behavior
Chrome 143 advertises brotli in the compress_certificate extension,
but some servers still send zlib-compressed certificates. Keep both
decompression handlers registered for compatibility.

Fixes TLS handshake failures with CERT_DECOMPRESSION_FAILED error
on servers using zlib certificate compression.
Changes to match Chrome 143's actual TLS fingerprint:

1. Certificate compression (compress_certificate extension 27):
   - Only advertise brotli (2), not zlib (1)
   - Chrome only supports brotli certificate compression
   - Servers compliant with RFC 8879 will only send brotli

2. Application settings (ALPS extension 17613):
   - Only advertise "h2" protocol, not "http/1.1"
   - Chrome only includes h2 in application_settings

3. Extension permutation:
   - Enable SSL_CTX_set_permute_extensions() to randomize extension order
   - Chrome randomizes extension order in each ClientHello
   - JA4 sorts extensions alphabetically so order doesn't affect JA4

Matching fingerprints:
- Cipher hash (JA4 part 2): 8daaf6152771 ✓
- Akamai HTTP/2: 1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p ✓
- compress_certificate: brotli only ✓
- application_settings: h2 only ✓

Note: Chrome fingerprint shows 17 extensions vs httpmorph's 16 because
Chrome capture was from a resumed session with pre_shared_key (41).
Fresh connections don't include pre_shared_key, which is expected behavior.
…n Windows

The HTTP/2 code was replacing the response body buffer (originally from
the buffer pool) with a newly malloc'd buffer, but not properly handling
the cleanup:

1. The original buffer from the pool was never returned to the pool
2. _buffer_pool was still pointing to the pool
3. _body_actual_size wasn't updated for the new buffer

When httpmorph_response_destroy() was later called, it tried to return
the malloc'd buffer to the buffer pool using the stale _body_actual_size,
causing heap corruption (especially visible on Windows with error code
0xc0000374).

Fix: Before assigning the new malloc'd buffer to response->body:
- Return the original buffer to the pool (if from pool) or free it
- Clear _buffer_pool since the new buffer is not from the pool
- Set _body_actual_size to track the actual allocation size

Fixes Windows CI heap corruption crash in Session.__del__
@arman-bd arman-bd merged commit 608decb into main Dec 10, 2025
40 of 42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants