TLS Fingerprinting in Playwright and Puppeteer: Detection and Bypass
Learn what JA3 and JA4 reveal about browser TLS handshakes, what Playwright and Puppeteer control, and how to test detection responsibly on systems you own.
TLS fingerprinting observes characteristics of a client’s TLS handshake, especially the ClientHello sent when a secure connection begins. JA3 and JA4 summarize selected handshake characteristics into identifiers that can help group client patterns. They do not, by themselves, prove that a visitor is using Playwright or Puppeteer, identify a person, or establish malicious intent.
Playwright and Puppeteer automate browsers through browser-control protocols. The browser and its network stack perform TLS negotiation, so observations can vary with browser engine and build, framework version, launch or attachment mode, protocol, network path, and session resumption. The available sources do not establish one universal TLS fingerprint for either framework or a generally reliable way to bypass fingerprint-based detection.
This guide explains the signals, their limits, and a reproducible workflow for authorized testing on systems you own or are permitted to assess.
1. What TLS fingerprinting sees in a ClientHello
During a TLS handshake, a client sends a ClientHello message containing information used to negotiate the connection. TLS 1.3 defines this handshake and its fields, including offered cipher suites and extensions. A fingerprinting system can derive a compact representation from selected characteristics of that message.
This is a network-level signal. It is distinct from properties visible to JavaScript after a page loads, such as browser APIs or rendered behavior. A page script and a TLS observer see different layers of the connection.
The client pattern is not a permanent identity. The observed characteristics can depend on the browser and connection context. A fingerprint can be useful for grouping similar handshakes, but it does not establish who is behind a connection.
2. What are JA3 and JA4 fingerprints?
JA3
The Salesforce JA3 project describes collecting decimal values for selected ClientHello fields: SSL version, accepted ciphers, extensions, elliptic curves, and elliptic-curve point formats. It concatenates the selected values into a string and hashes that string with MD5 to produce a compact fingerprint. The project says JA3 was created at Salesforce in 2017 and is no longer actively maintained by Salesforce.
JA3 is a representation of selected handshake characteristics, not a cryptographic proof of software identity. The same hash can be associated with a client pattern without proving that every connection with that hash came from the same application or automation framework.
JA4
JA4 is another TLS-client identifier. Cloudflare explains that JA4 sorts ClientHello extensions. This makes grouping modern-browser fingerprints easier by reducing the number of unique fingerprints caused by extension ordering. JA4 remains a grouping signal, not a person-level identifier or a standalone bot verdict.
| Aspect | JA3 | JA4 |
|---|---|---|
| Input | Selected ClientHello characteristics | TLS client handshake characteristics |
| Notable method detail | Selected values are concatenated and hashed | ClientHello extensions are sorted to aid grouping |
| Interpretation | A client-pattern identifier | A client-pattern identifier designed to group modern-browser variations more easily |
| What it does not prove | That a session is a bot, a person, or a particular framework | That a session is a bot, a person, or a particular framework |
3. How Playwright and Puppeteer relate to TLS
Playwright and Puppeteer control browser behavior; they do not replace the browser’s TLS handshake with one fixed framework-wide fingerprint. The browser engine and build, network stack, connection route, and TLS session state all matter to what a network observer sees. This is an architectural inference from how browsers perform TLS negotiation and how the automation frameworks connect to browser processes, not a controlled result demonstrating a universal fingerprint for each framework.
Playwright details that affect comparisons
- Playwright can launch Chromium, Firefox, or WebKit, or attach to an existing browser instance. Record the engine and exact browser build when comparing results.
- Its documentation warns that custom browser arguments can break functionality. A run using custom arguments may not be comparable to a normal launch.
- Playwright’s documentation describes attachment through the Chrome DevTools Protocol (CDP) as lower fidelity than its own Playwright protocol connection. Record whether the browser was launched or attached and which connection mode was used.
Puppeteer details that affect comparisons
- Puppeteer uses CDP for Chrome by default and also supports WebDriver BiDi for Chrome and Firefox.
- Puppeteer releases are tied to particular browser revisions for protocol compatibility. Record the Puppeteer version and browser revision rather than treating “Puppeteer” as one fixed client.
These details explain why a useful report names the automation framework, version, browser engine and build, protocol, launch or attachment mode, and network path. The sources do not support a universal ranking of Playwright versus Puppeteer detection or bypass success.
4. What a fingerprint can and cannot prove
A detector may use JA3 or JA4 as one network signal alongside other context. The cited Cloudflare documentation describes its fingerprint fields and their availability; it does not publish universal bot-classification accuracy. The JA3 project describes fingerprinting client applications and threat-intelligence use cases, but its examples do not establish present-day accuracy for Playwright or Puppeteer traffic.
- A match can suggest: a handshake pattern resembles a pattern the detector has observed or grouped.
- A mismatch can suggest: the handshake differs from that pattern, or that the observation conditions changed.
- Neither result proves: human identity, bot status, malicious intent, successful evasion, or a particular automation framework.
Do not treat a fingerprint as a verdict on its own. Confirm that the detector received a value, understand which network connection it describes, and interpret it in the context of the detector’s documented behavior.
5. Missing fingerprints, session resumption, and product availability
Fingerprint data may be absent. Cloudflare documents cases where its JA3 or JA4 fields can be null or empty, including non-encrypted HTTP traffic, certain Worker-to-zone or third-party routing paths, skipped Bot Management, and later connections that use TLS session resumption. Its Workers documentation advises handling missing JA4 Signals fields.
These are Cloudflare-specific conditions. They should not be assumed to describe every detector or deployment. A missing value means the signal is unavailable in that observation; it does not mean that the connection is benign or that a detector has been bypassed.
Cloudflare states that JA3 and JA4 are available to Enterprise customers who have purchased Bot Management. Check the current product documentation and your deployment’s access before building a test around those fields.
6. Can Playwright change its TLS fingerprint?
The sources do not demonstrate a generally reliable Playwright setting that changes the TLS fingerprint in a predictable way, nor do they establish a broadly reliable bypass. Playwright’s custom browser arguments can affect browser behavior, but its documentation warns that custom arguments may break functionality; that is not evidence that a particular argument safely or consistently changes a handshake fingerprint.
For authorized diagnostics, treat a changed observation as a result to investigate, not as proof that a detector was defeated. Record the browser build, framework version, protocol and attachment mode, connection route, TLS termination point, and session-resumption status. Avoid making claims from comparisons where those conditions differ.
7. Does rotating an IP change a TLS fingerprint?
An IP address and a TLS ClientHello fingerprint describe different parts of a connection. Changing the network route or source address does not, by itself, establish that the browser’s ClientHello characteristics changed. Conversely, the same client pattern may be observed across different network paths. A detector can consider both network and TLS context, but the cited sources do not define a universal relationship or prove that IP rotation bypasses TLS fingerprinting.
In a controlled test, record the source and route as context while comparing the handshake fields independently. Keep the browser, build, protocol, endpoint, and session conditions fixed where possible.
8. How can I test TLS fingerprint detection on my own site?
- Confirm authorization and scope. Use a staging environment or a system you own or are permitted to assess. Identify the endpoint, detector, and network path in scope.
- Record the test setup. Capture the exact browser engine and build, Playwright or Puppeteer version, launch or attachment mode, browser-control protocol, operating environment, and network route.
- Identify the fingerprint method. Determine whether the detector exposes JA3, JA4, or another signal. Check its documentation for availability requirements and conditions that produce missing values.
- Make repeated controlled observations. Keep the setup stable between runs, and note whether a connection may have resumed a TLS session. Compare like with like rather than combining runs with different browser builds or routes.
- Verify field presence before interpreting a decision. If the fingerprint field is null, empty, or unavailable, do not attribute the detector’s result to that fingerprint.
- Report limits clearly. State the observed values and conditions, the detector context, and what the test cannot establish. A small controlled comparison does not prove universal detection accuracy.
Comparison record
| Record | Why it matters |
|---|---|
| Browser engine and exact build | The browser performs the TLS negotiation. |
| Framework and version | Framework releases and browser compatibility can differ. |
| Protocol and launch or attachment mode | Playwright and Puppeteer support different browser-control paths. |
| Fingerprint method and field presence | JA3 and JA4 are distinct methods; an absent field cannot support a fingerprint-based conclusion. |
| Endpoint, network path, and TLS termination point | Routing and termination affect which handshake the detector can observe. |
| Session-resumption status | Cloudflare documents cases where resumed connections do not provide the fingerprint field. |
| Detector and product configuration | Signal access and behavior depend on the deployment. |
9. Troubleshooting test results
| Symptom | Likely cause | What to check |
|---|---|---|
| JA3 or JA4 is null or empty | The field may be unavailable for this traffic or route; the detector may be skipped; the connection may be resumed. | Check encryption, routing and Worker paths, Bot Management execution, session state, and the vendor’s field-availability documentation. |
| Two runs produce different results | Browser build, framework version, protocol, launch mode, route, or connection state may differ. | Compare the full test record and repeat with the relevant conditions held constant. |
| A detector labels a session without a fingerprint | It may be using other signals, or the fingerprint may not be exposed in the place being inspected. | Check detector logs and field availability. Do not assume the decision came from JA3 or JA4. |
| A custom Playwright launch behaves differently | Custom browser arguments can affect functionality. | Review the arguments and compare with a documented standard launch before drawing conclusions. |
| CDP attachment differs from a Playwright launch | Playwright documents CDP attachment as lower fidelity than its own protocol connection. | Record the connection mode and compare the same mode across runs. |
| Framework names appear to predict detection inconsistently | “Playwright” or “Puppeteer” omits the browser build, protocol, and network conditions. | Report the complete comparison axes instead of assigning one fixed fingerprint to a framework. |
10. Performance, reliability, and cost considerations
TLS fingerprinting observes connection-establishment characteristics; it is not a measure of page rendering quality or browser automation reliability. The cited sources provide no benchmark for the time or resource cost of JA3 or JA4 detection and no universal accuracy figure, so avoid extrapolating one from sample hashes or example signals.
For reliable diagnostics, distinguish a missing field from a changed value, record session resumption and network routing, and use repeated runs with stable browser and protocol versions. If the detector’s signal is unavailable in your plan or deployment, arrange access through the vendor or use the observability supported by your environment rather than treating an empty field as a test result.
For cost planning, Cloudflare’s cited documentation limits JA3 and JA4 access to Enterprise customers with Bot Management. It does not establish a price here. Confirm current eligibility and pricing directly with the vendor before budgeting.
11. Or skip the browser setup
If your goal is to capture a page for a report or visual check rather than study its TLS handshake, ScreenshotNeo is a website screenshot API and MCP server for developers. It does not replace an authorized TLS-fingerprinting test: use the browser-and-detector workflow above when the handshake itself is what you need to measure.
One GET request returns an image or PDF. For example, cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));
See the ScreenshotNeo API documentation for request options. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000.
Sign up free for 1,000 screenshots a month, no card required.
12. FAQ
Does a JA3 or JA4 value stay the same forever?
No. It describes selected handshake characteristics and should be read as a client-pattern signal, not an immutable identity.
Can a missing JA4 value mean the request passed detection?
No. Missing means the field was not available in that observation. The detector may use other signals, and the reason the field is absent depends on the deployment.
Can I conclude that Playwright was used from a fingerprint alone?
No. The cited sources do not establish a universal Playwright fingerprint or show that a matching fingerprint conclusively identifies the framework.
Is there a proven universal bypass?
The cited sources do not demonstrate one. Keep testing authorized, describe the exact conditions, and avoid treating a changed fingerprint as proof of evasion.


