Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
06b0957
New JA3 for Safari mobile
NgaoDaCoPho Sep 26, 2025
4887a40
Add fix for Python 3.12+
NgaoDaCoPho Sep 26, 2025
7ac5a6d
Make it work with default tlslite-ng
NgaoDaCoPho Sep 26, 2025
e2256fd
Update database, handshake fix
NgaoDaCoPho Sep 26, 2025
e49989d
Database Update
NgaoDaCoPho Sep 26, 2025
1d70092
Delete .claude directory
AnCry1596 Sep 26, 2025
44ae309
Remove cladue
NgaoDaCoPho Sep 26, 2025
399f837
Update .gitignore
AnCry1596 Sep 26, 2025
ba243a3
Merge branch 'master' of https://github.com/AnCry1596/httpx-tls
NgaoDaCoPho Sep 26, 2025
25d4d4e
Merge branch 'master' of https://github.com/AnCry1596/httpx-tls
NgaoDaCoPho Sep 26, 2025
4597e07
Database update
NgaoDaCoPho Sep 26, 2025
36804a5
README update
NgaoDaCoPho Sep 26, 2025
2b724a7
Delete .claude directory
AnCry1596 Sep 26, 2025
592b857
Add new mapping, update DB
NgaoDaCoPho Sep 26, 2025
b9af996
Add Firefox upto 143
NgaoDaCoPho Sep 26, 2025
2fe512d
Update a fix for database
NgaoDaCoPho Sep 26, 2025
995aa2e
Update README
NgaoDaCoPho Sep 27, 2025
d3aabae
Fix
NgaoDaCoPho Sep 27, 2025
cf9c3a5
Update requirements.txt
NgaoDaCoPho Sep 27, 2025
9cb2189
Fix problem with chrome iOS
NgaoDaCoPho Sep 28, 2025
5d8e093
Fix for Edge iOS
NgaoDaCoPho Sep 29, 2025
4b6101b
Added Chrome 141
NgaoDaCoPho Oct 7, 2025
e9d32f4
Fix akamai for Firefox Mobile 136-143 and Chromium 141
NgaoDaCoPho Oct 10, 2025
ea6d751
Added support for SamsungBrowser
NgaoDaCoPho Oct 10, 2025
37f4b36
Added Support for YandexBrowser and DuckDuckGo
NgaoDaCoPho Oct 10, 2025
c34a74e
Added Support for Vivaldi
NgaoDaCoPho Oct 10, 2025
77e6f51
Added Support for Google Apps
NgaoDaCoPho Oct 10, 2025
fba2fda
Better User Agent Parsing and Handle mostly Posible useragent
NgaoDaCoPho Oct 11, 2025
48964da
Fix UA parsing Gone wrong on Safari iOS 26
NgaoDaCoPho Oct 11, 2025
9ee4f6e
Move akamai string of Firefox and Chrome to MacOS, fix Wrong Safari D…
NgaoDaCoPho Oct 12, 2025
9a0a732
Move to Cleaned ja3 string for Chrome And Firefox
NgaoDaCoPho Oct 12, 2025
3ab0bb0
Added Firefox 144, Fix for Chrome 120-141
NgaoDaCoPho Oct 16, 2025
7f92add
Added Akamai string for Firefox 144 Desktop and Mobile
NgaoDaCoPho Oct 16, 2025
ee785ab
Fix Safari 18
NgaoDaCoPho Oct 19, 2025
44dbc1f
Ignore SETTINGS_NO_RFC7540_PRIORITIES
NgaoDaCoPho Oct 19, 2025
4d499fa
Random TLS extension order
NgaoDaCoPho Oct 30, 2025
23066b8
Update setup.py
NgaoDaCoPho Oct 30, 2025
195cf99
Update setup.py
NgaoDaCoPho Oct 30, 2025
0df3c10
Added Chrome 142
NgaoDaCoPho Nov 7, 2025
3355760
Added support for Firefox 145
NgaoDaCoPho Nov 12, 2025
89e9e0c
Add Chrome 143
NgaoDaCoPho Dec 15, 2025
24a7ed9
Add Firefox 146
NgaoDaCoPho Dec 28, 2025
46bb234
Add Support for chrome 144
NgaoDaCoPho Jan 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ dmypy.json
# Cython debug symbols
cython_debug/

# End of https://www.toptal.com/developers/gitignore/api/python

examples/
examples/
*test*
.claude
.claude/
tlslite-ng
140 changes: 140 additions & 0 deletions RANDOM_EXTENSION_ORDER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Random TLS Extension Order Feature

## Overview

Random TLS extension order is **enabled by default** in httpx-tls. This feature randomizes the order of TLS extensions in the ClientHello message to help avoid fingerprinting and make connections less predictable while maintaining full protocol compatibility.

## Why Randomize Extension Order?

TLS fingerprinting tools and WAFs often use the specific order of TLS extensions as part of their fingerprinting process. By randomizing the extension order:

- **Reduces fingerprinting**: Each connection can have a different extension order
- **Maintains compatibility**: All required extensions are still sent, just in random order
- **Bypasses detection**: Some security systems key on specific extension patterns

## Usage

### Default Behavior (Randomization Enabled)

By default, all TLS profiles have randomization enabled:

```python
from httpx_tls import AsyncTLSClient
from httpx_tls.profiles import TLSProfile

# Randomization is enabled by default
client = AsyncTLSClient(
tls_config=TLSProfile.create_from_version('chrome', 120)
)

# Or with JA3 string
profile = TLSProfile.create_from_ja3(ja3) # Randomization enabled by default

# Or with user agent
profile = TLSProfile.create_from_useragent(user_agent) # Randomization enabled by default
```

### Disabling Randomization (for exact JA3 matching)

If you need exact JA3 fingerprint matching, you can disable randomization:

```python
from httpx_tls.profiles import TLSProfile
from httpx_tls import AsyncTLSClient

# Disable in TLSProfile creation
profile = TLSProfile.create_from_ja3(ja3, randomize_extensions=False)

# Or when creating from version
profile = TLSProfile.create_from_version('chrome', 120, randomize_extensions=False)

# Or in AsyncTLSClient
client = AsyncTLSClient(
tls_config=profile,
randomize_tls_extensions=False
)
```

### Direct TLSProfile Instantiation

```python
from httpx_tls.profiles import TLSProfile

# With randomization (default)
profile = TLSProfile(
tls_version=(3, 4),
ciphers=[4865, 4866, 4867],
extensions=[51, 23, 13, 45, 65281, 5, 43],
groups=[29, 23, 24]
# randomize_extensions=True is the default
)

# Without randomization
profile = TLSProfile(
tls_version=(3, 4),
ciphers=[4865, 4866, 4867],
extensions=[51, 23, 13, 45, 65281, 5, 43],
groups=[29, 23, 24],
randomize_extensions=False
)
```

## Example Output

**Without randomization:**
```
Extensions: [51, 23, 13, 45, 65281, 5, 43]
```

**With randomization (3 different runs):**
```
Run 1: [13, 23, 43, 65281, 51, 5, 45]
Run 2: [43, 45, 5, 13, 23, 65281, 51]
Run 3: [45, 23, 51, 13, 65281, 5, 43]
```

## Implementation Details

### Changes Made

1. **profiles.py**:
- Added `randomize_extensions` parameter to `TLSProfile.__init__()`
- Implemented `_randomize_extension_order()` method
- Updated `_set_order()` to apply randomization and enable `extension_order`
- Re-enabled the previously commented-out `settings.extension_order` assignment

2. **client.py**:
- Added `randomize_tls_extensions` parameter to `AsyncTLSClient.__init__()`
- Automatically applies randomization flag to TLSProfile if provided

### Technical Notes

- Extension randomization uses Python's `random.shuffle()` for unpredictable ordering
- All extensions from the original profile are preserved, only the order changes
- The randomization happens at profile creation time
- Each new TLSProfile instance with randomization enabled will have a different order

## Security Considerations

- **Compatibility**: Randomizing extension order is generally safe and maintains TLS protocol compatibility
- **Fingerprint Variation**: Each connection will have a unique fingerprint when randomization is enabled
- **Performance**: Minimal overhead - randomization happens once during profile creation

## Testing

Run the included test and example scripts:

```bash
# Run basic tests
python test_randomization.py

# Run usage examples
python example_random_extensions.py
```

## Related Files

- [profiles.py](httpx_tls/profiles.py) - TLS profile implementation with randomization
- [client.py](httpx_tls/client.py) - AsyncTLSClient with randomization support
- [test_randomization.py](test_randomization.py) - Test script
- [example_random_extensions.py](example_random_extensions.py) - Usage examples
126 changes: 101 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# A pure python TLS client that integrates with httpx.

Not ready yet, check back soon!
A comprehensive TLS fingerprinting library that seamlessly integrates with httpx for advanced browser impersonation and anti-detection capabilities.


## Purpose

I made this library mostly because there wasn't an open-sourced TLS client written in Python. Because most clients were
Expand Down Expand Up @@ -33,21 +32,35 @@ httpx-tls properly supports Python's asynchronous libraries without resorting to
supported by httpx-tls as well.

5. **Built-in UA Parsing**:
Unlike traditional TLS clients, httpx-tls does the heavy-lifting for you to create appropriate TLS fingerprints that
match the browser you want. Thanks to a comprehensive database created from scraping years worth of open-sourced changes
in popular browsers (and some manual testing), you simply need to pass in the user-agent string for which you want the
fingerprint for and httpx-tls will automatically use one for the specific device-os-browser combination. Currently,
this built-in parsing is supported for Chromium browsers (Opera, Edge, Chrome), Firefox, and Safari. Both desktop and
mobile devices' (iOS + android) user-agent strings are supported. A full list of supported browser versions can be found
Unlike traditional TLS clients, httpx-tls does the heavy-lifting for you to create appropriate TLS fingerprints that
match the browser you want. Thanks to a comprehensive database created from scraping years worth of open-sourced changes
in popular browsers (and some manual testing), you simply need to pass in the user-agent string for which you want the
fingerprint for and httpx-tls will automatically use one for the specific device-os-browser combination. Currently,
this built-in parsing is supported for Chromium browsers (Opera, Edge, Chrome), Firefox, and Safari. Both desktop and
mobile devices' (iOS + android) user-agent strings are supported. A full list of supported browser versions can be found
later.

6. **Extensible**
Browsers and their fingerprints are dynamic and httpx-tls recognizes that. Apart from just parsing user-agents to create
fingerprints automatically, you can also pass in a custom ja3 string for TLS fingerprint or akamai string for http2
6. **Extensible**:
Browsers and their fingerprints are dynamic and httpx-tls recognizes that. Apart from just parsing user-agents to create
fingerprints automatically, you can also pass in a custom JA3 string for TLS fingerprint or Akamai string for HTTP/2
fingerprint and httpx-tls will use that instead.

7. **Random TLS Extension Order** (Enabled by Default):
httpx-tls automatically randomizes the order of TLS extensions in the ClientHello message to reduce fingerprinting
and make connections less predictable. This anti-detection feature is enabled by default and helps bypass security
systems that rely on specific extension patterns. All required extensions are still sent to maintain full protocol
compatibility, just in a randomized order each time a connection is established.

## Usage

Requirements
```
pip install -r requirements.txt
# or manually install the modified tlslite-ng:
pip install -e tlslite-ng/
```
Other requirements can be found in setup.py

As mentioned before, httpx-tls integrates with httpx and much of its usage is similar. To create fingerprints, use the
TLSProfile and Http2Profile classes and pass them to the async client during its creation. For example, to use httpx-tls with trio
and the built-in user-agent parsing (the code is pretty much the same for asyncio as well):
Expand All @@ -66,13 +79,15 @@ and the built-in user-agent parsing (the code is pretty much the same for asynci
# Create TLS and http2 fingerprints using the useragent
tls_config = TLSProfile.create_from_useragent(ua)
h2_config = Http2Profile.create_from_useragent(ua)

# Use AsyncTLSClient provided by httpx-tls
client = AsyncTLSClient(h2_config=h2_config, tls_config=tls_config, http2=True)

# Rest of the API is same as httpx
response = await client.get("https://tools.scrapfly.io/api/fp/ja3")
response = await client.get("https://get.ja3.zone")
print(response.text)

await client.aclose()


trio.run(main)
Expand All @@ -95,37 +110,98 @@ To use httpx-tls with a custom http2 and TLS fingerprint:
# Create TLS and http2 fingerprints using the stored strings
tls_config = TLSProfile.create_from_ja3(ja3)
h2_config = Http2Profile.create_from_akamai_str(akamai_str)

# Use AsyncTLSClient provided by httpx-tls
client = AsyncTLSClient(h2_config=h2_config, tls_config=tls_config, http2=True)

# Rest of the API is same as httpx
response = await client.get("https://tools.scrapfly.io/api/fp/ja3")
response = await client.get("https://get.ja3.zone")
print(response.text)

await client.aclose()


trio.run(main)
```

### Random TLS Extension Order

By default, httpx-tls randomizes the order of TLS extensions to improve anti-detection. This feature is **enabled by default**.

To **disable** randomization if you need exact JA3 fingerprint matching:

```python
from httpx_tls.profiles import TLSProfile
from httpx_tls.client import AsyncTLSClient

# Disable randomization in TLSProfile
tls_config = TLSProfile.create_from_ja3(ja3, randomize_extensions=False)

# Or disable in AsyncTLSClient
client = AsyncTLSClient(
tls_config=tls_config,
randomize_tls_extensions=False # Disable randomization
)
```

**Note**: When randomization is enabled (default), each new connection will have a different extension order,
making your fingerprint less predictable and harder to detect.

## Precautions (read this section before using httpx-tls)

While I designed httpx-tls to not have obscure surprises in its API, there still are a few differences between httpx-tls
and httpx (mostly because of the underlying third-party dependencies) which are summarised below:

1. Certificate Verification:
1. **Certificate Verification**:
httpx-tls does no certificate verification at all. Essentially, you can assume that the `verify` parameter when creating
a client will always be equivalent to False. Adding client certificates is planned a feature, but it does not work
a client will always be equivalent to False. Adding client certificates is a planned feature, but it does not work
right now.

2. Sync support
Currently, httpx-tls only offers asynchronous support, but I do plan to add sync support soon.
2. **Sync Support**:
Currently, httpx-tls only offers asynchronous support, but sync support is planned for future releases.

3. TLS 1.2
TLS 1.2 is supported by httpx-tls, but is not yet well tested enough. TLS 1.3, the current web standard, is fully
3. **TLS 1.2**:
TLS 1.2 is supported by httpx-tls, but is not yet well tested enough. TLS 1.3, the current web standard, is fully
supported and tested.

4. General bugs
httpx-tls is an ambitious project which currently does not have a test-suite. Please report any bugs you come across.
4. **General Bugs**:
httpx-tls is an ambitious project which currently does not have a comprehensive test-suite. Please report any bugs you encounter through the GitHub issues.


## Supported Browsers

The enhanced fingerprint database now supports a comprehensive range of browser versions:

### Chrome/Chromium
- Versions 73-140
- Desktop and Android variants
- Latest TLS 1.3 extensions and cipher suites

### Firefox
- Versions 65-145
- Desktop and mobile variants
- Support for Firefox-specific TLS extensions

### Safari
- Versions 13-26 (both desktop and iOS)
- Comprehensive iOS Safari fingerprints
- Support for Safari-specific TLS behaviors

### Edge
- Versions 99-140?
- Built on Chromium fingerprints

## Recent Enhancements

- **Random TLS Extension Order** (NEW): Automatic randomization of TLS extensions enabled by default to reduce fingerprinting
- **Expanded Browser Coverage**: Added 30+ new browser version ranges based on curl_cffi fingerprint database
- **Enhanced JA3 Accuracy**: Updated TLS fingerprints with modern extension support
- **Improved Anti-Detection**: Successfully bypasses Cloudflare protection on sites like audiobooks.com
- **Modified tlslite-ng**: Custom TLS library with precise cipher/extension order control

## Special Thanks To

- [charxhit](https://github.com/charxhit) for the original [httpx-tls](https://github.com/charxhit/httpx-tls)
- [tlsfuzzer](https://github.com/tlsfuzzer) for the original [tlslite-ng](https://github.com/tlsfuzzer/tlslite-ng)
- [lexiforest](https://github.com/lexiforest) for [curl_cffi](https://github.com/lexiforest/curl_cffi) fingerprint database insights
- [encode](https://github.com/encode) for [httpx](https://github.com/encode/httpx)
Loading
Loading