โ† Projects
01 / 09 - C++ ยท Chromium ยท Network Security

Chromium TLS
Fingerprint Engine

A custom Windows Chromium build that exposes a Chrome DevTools Protocol command to configure TLS ClientHello parameters - JA3/JA3N fingerprint spoofing - at runtime. Paired with a Python playwright_tls package.

C++Chromium BoringSSLPython PlaywrightCDP
View on GitHub โ†—

What it does

Anti-bot systems like Cloudflare, Akamai and DataDome fingerprint the TLS ClientHello to tell real browsers from automation. This project patches Chromium and BoringSSL to make that handshake fully controllable from your automation code.

Parameters flow from Python through Playwright and CDP into the browser and network service, down to BoringSSL, producing a custom ClientHello on every HTTPS connection - no proxy or TLS-termination layer required.

Key capabilities

01
Runtime control
Cipher suites, supported groups and curves, TLS version bounds and exact extension ordering - all set per session.
02
JA3 one-liner
Feed a standard JA3 string and the wrapper configures the whole handshake in a single call.
03
Browser presets
Ready-made fingerprints for Chrome, Firefox, Edge, Safari and curl.
04
Extension permutation
Per-connection randomisation matching Chrome 110+ behaviour, or a fixed order for older targets.
05
Playwright wrapper
Async and sync BrowserWithTLS helpers drop straight into existing Playwright automation.

Data flow

01
Python client
Your script calls set_fingerprint() or set_ja3() on the BrowserWithTLS wrapper.
02
CDP command
The wrapper issues Emulation.setTLSFingerprint over the Chrome DevTools Protocol.
03
Mojo IPC
The browser process forwards the parameters to the network service through a Mojo interface.
04
BoringSSL
A patched SSL_set_extension_order() builds the custom ClientHello on every new socket.

Build from source

Windows 10/11 x64 with roughly 250 GB of disk. The whole build is scripted in PowerShell:

powershell
# one-time prerequisites
.\build\install_prerequisites_windows.ps1

# build Chromium (matches a Playwright revision)
.\build\build_chromium_windows.ps1 -PlaywrightVersion 1.44.0

# install the Python wrapper
pip install -e .

Drive it from Python

python
import asyncio
from playwright.async_api import async_playwright
from playwright_tls import BrowserWithTLS, CHROME_124_WIN

async def main():
    async with async_playwright() as p:
        async with BrowserWithTLS(p, executable_path=r"dist\chrome.exe") as browser:
            await browser.set_fingerprint(CHROME_124_WIN)
            page = await browser.new_page()
            await page.goto("https://tls.peet.ws/api/all")
            print(await page.text_content("body"))

asyncio.run(main())

Note: EC point formats beyond uncompressed are logged but not applied, and ALPN / HTTP-2 negotiation stays independent of the TLS fingerprint.