Encrypted traffic hides what a client sends, but the TLS ClientHello that opens every session is sent in the clear and reveals which software built it. JA3 and its successor JA4 turn that handshake into a short, shareable fingerprint, so defenders can spot malware, scripts and bots by how they connect rather than where they connect to. This guide explains exactly how JA3 and JA4 are computed, why randomised ClientHellos broke JA3 and how JA4 copes, what the wider JA4+ suite adds, and how to build allow lists, deny lists and threat hunts that hold up in production. It is for detection engineers, threat hunters, network security and web application protection teams. For the wider sensor, telemetry and response picture, see the NDR Guide; this page goes deeper on the fingerprints only.
Key takeaways
- A fingerprint identifies a TLS stack, not a person or a program. Every client built on the same library and settings shares a fingerprint, so JA3 and JA4 are strong pivots and weak verdicts on their own.
- JA4 sorts what JA3 kept in order. JA4 sorts cipher suites and extensions before hashing, which keeps a stable fingerprint when a client shuffles their order, as Chromium browsers began doing with extensions in 2023.
- JA4 is readable before it is hashed. The first part (for example
t13d1516h2) shows transport, TLS version, SNI presence, cipher and extension counts and ALPN, so analysts can filter and group without a lookup table. - Allow lists beat deny lists. Where only a few clients should talk to a service, alerting on any fingerprint outside the expected set is far more reliable than chasing malware hashes that change with each library update.
- Check the licence before you build it into a product. JA4 itself is BSD 3-Clause; the rest of JA4+ (JA4S, JA4H, JA4X, JA4SSH, JA4T and others) is under the FoxIO License 1.1, which permits internal security use but requires an OEM licence for vendors who sell it.
Why the ClientHello can be fingerprinted
A TLS session starts with the client's ClientHello. It lists the protocol versions, cipher suites, extensions, supported groups and signature algorithms the client supports, plus the server name (SNI) and application protocols (ALPN) it wants. Which values appear, and in what order, depends on the TLS library and how the application configured it. Two different programs built on different libraries produce different ClientHellos even when they connect to the same server. The JA3 project describes this as the basis of the method: the negotiation is sent in the clear, so client applications can be identified from it.
TLS 1.3 did not remove the signal. The JA4 project's documentation argues that TLS 1.3 makes client fingerprinting easier, because clients send a larger set of extensions, and browsers and applications still offer many more cipher suites than TLS 1.3 itself defines. Encrypted Client Hello changes what an on-path sensor sees, because the sensitive inner ClientHello is encrypted; see the Encrypted Client Hello Guide before relying on SNI-based logic. For the handshake itself, see the How TLS Works Guide.
GREASE values are noise by design. RFC 8701 (Informational, January 2020) reserves values such as 0x0A0A to 0xFAFA that clients may insert at random into cipher suites, extensions, named groups, signature algorithms and supported versions to keep servers tolerant of unknown values. Both JA3 and JA4 ignore GREASE values completely, so a client that uses GREASE still produces one fingerprint.
How JA3 and JA3S are computed
JA3 was published by Salesforce in 2017. Its repository now states that the project is no longer actively maintained by Salesforce and points to JA4 as the latest work by the original author.
- Collect five fields from the ClientHello: TLS version, accepted cipher suites, list of extensions, elliptic curves (supported groups) and elliptic curve point formats.
- Write them as decimal values: values within a field joined with
-, fields joined with,, in the order they appear in the packet. Empty fields stay empty. - Hash the string with MD5 to give a 32 character fingerprint.
JA3S applies the same idea to the ServerHello, using version, chosen cipher and extensions. Because a server answers the same client the same way, the JA3 and JA3S pair fingerprints the whole negotiation; the JA3 project uses command and control servers that always answer their implant identically as its example.
The weakness is ordering. JA3 keeps fields in packet order, so any client that shuffles cipher suites or extensions produces many JA3 values for one program. The JA4 project describes "cipher stunting", randomising cipher order to defeat JA3, and notes that in 2023 Google updated Chromium browsers to randomise extension order, which it describes as another tactic that defeats JA3 and was intended to stop servers depending on a fixed Chrome fingerprint. The MD5 hash also hides everything about the client, so a JA3 value is useless without a lookup.
How JA4 is computed
JA4 is written in three parts separated by underscores, a_b_c. The specification's example is t13d1516h2_8daaf6152771_e5627efa2ab1.
| Part | Content | Example value |
|---|---|---|
| a: transport | t TLS over TCP, q QUIC, d DTLS | t |
| a: version | Highest value in the supported_versions extension (0x002b) if present, ignoring GREASE; otherwise the protocol version. 13, 12, 11, 10, s3, s2, DTLS d1 to d3 | 13 |
| a: SNI | d if the SNI extension is present (going to a domain), i if absent (going to an IP address) | d |
| a: cipher count | Two digit count of cipher suites, ignoring GREASE, capped at 99 | 15 |
| a: extension count | Two digit count of extensions, ignoring GREASE, including SNI and ALPN | 16 |
| a: ALPN | First and last alphanumeric characters of the first ALPN value; 00 if none | h2 (http/1.1 gives h1) |
| b: cipher hash | SHA-256 of the cipher suite hex codes, sorted, comma separated, truncated to 12 characters | 8daaf6152771 |
| c: extension hash | SHA-256 of the sorted extension hex codes (SNI 0000 and ALPN 0010 removed), then an underscore and the signature algorithms in original order, truncated to 12 characters | e5627efa2ab1 |
Three design choices matter for detection:
- Sorting: ciphers and extensions are sorted before hashing, so order shuffling does not change the fingerprint. The project's research found that applications differ more by which ciphers they choose than by their order. Signature algorithms are kept in original order to preserve uniqueness.
- Destination independence: SNI and ALPN are removed from the c hash, so the same application has the same c part whether it connects to a domain or an IP, or changes ALPN.
- Raw forms: the specification defines a raw output (
JA4_r, sorted values before hashing) and an original order output (JA4_o, GREASE removed, SNI and ALPN kept). Store the raw form where storage allows; it lets analysts see which cipher or extension made two fingerprints differ.
The JA4 project states plainly that fingerprints change as application TLS libraries are updated, about once a year, and that defenders should not assume they stay constant where software is updated.
The JA4+ suite
| Method | What it fingerprints | Typical defensive use |
|---|---|---|
| JA4 | TLS, QUIC and DTLS ClientHello | Client application identity, allow lists, bot and malware hunting |
| JA4S | Server response to a client | Pair with JA4 to identify a specific client and server combination such as a C2 framework |
| JA4H | HTTP client request | HTTP client identification, for example malware droppers, where HTTP is visible |
| JA4X | X.509 TLS certificates | Grouping certificates produced by the same tooling |
| JA4SSH | SSH traffic | Reverse shell detection |
| JA4T and JA4TS | TCP client and server | Operating system and network path characteristics |
| JA4L and JA4LS | Latency between client and server | Latency and light distance estimates |
| JA4D and JA4D6 | DHCP and DHCPv6 | Device type identification on the local network |
Licensing: the JA4 repository states that JA4 is open source under BSD 3-Clause, the same as JA3, and that FoxIO has no patent claims on it. JA4S, JA4L, JA4LS, JA4H, JA4X, JA4SSH, JA4T, JA4TS, JA4D, JA4D6 and the scanning methods are described as patent pending and licensed under the FoxIO License 1.1, which the project says permits internal business and academic use but not monetisation; vendors selling JA4+ need an OEM licence. Check current terms in the repository before embedding any JA4+ method in a product or a managed service.
Where to collect fingerprints
Tools are listed alphabetically; order is not a ranking.
| Collection point | Fingerprints and setting | Notes |
|---|---|---|
| Amazon Web Services: AWS WAF | "JA3 fingerprint" and "JA4 fingerprint" request components, used in string match, regex match, regex pattern set and size constraint statements | Available on Amazon CloudFront distributions and Application Load Balancers. A fallback behaviour (match or no match) must be set for when a fingerprint cannot be calculated. Fingerprints appear in web ACL logs. |
| Arkime | JA4+ fields in session data | Listed by the JA4 project as its recommended open-source JA4+ tool. |
| Cloudflare | JA3 and JA4 in Bot Analytics, Security Events, Security Analytics, logs, WAF custom rules, Transform Rules and Workers; JA4 Signals exposed to Workers | Availability: Enterprise customers with Bot Management. Documentation describes block or challenge, skip (allow) and mobile app allow list uses. |
| Suricata | Rule keywords ja3.hash, ja3.string, ja3s.hash, ja3s.string, ja4.hash; settings app-layer.protocols.tls.ja3-fingerprints and ja4-fingerprints | Enabled automatically when a loaded rule needs it unless set to no. Support can be compiled out, so rules should declare requires: feature ja4; (or ja3). |
| Wireshark | JA4+ plugin from the JA4 project | For analyst inspection of captures rather than continuous monitoring. |
| Zeek | JA3 and JA3S scripts from the JA3 project; JA4+ package from the JA4 project | Adds fingerprint fields to Zeek's TLS and related logs for SIEM use. |
Sensor position decides what you see. A fingerprint is only meaningful at the point where the client's own TLS session is visible. Behind a TLS-terminating proxy, load balancer or secure web gateway, internal sensors see the proxy's ClientHello for outbound traffic and the edge device's view for inbound traffic. Collect at the egress before the proxy for endpoint hunting, and at the edge (CDN, WAF or load balancer) for inbound bot and abuse detection.
Evasion and its limits
Defenders should plan for clients that try to change or copy their fingerprint. Without going into technique, the patterns to expect are:
- Order randomisation: shuffling cipher suites or extensions. This defeats JA3 but not JA4, because JA4 sorts both lists.
- Content randomisation: adding or dropping ciphers or extensions per connection. This changes the JA4 b or c hash; the a part (counts, version, ALPN) and JA4_r still show the near-duplicates, so hunt on clusters rather than single hashes.
- Impersonation: a script or bot reproducing a mainstream browser's ClientHello. The TLS fingerprint then looks ordinary, so combine it with other layers: the HTTP header fingerprint (JA4H), the TCP fingerprint (JA4T), the claimed User-Agent, and behaviour.
- Using common libraries: malware built on the operating system's own TLS stack or a popular language runtime shares fingerprints with large amounts of legitimate software. That makes deny-listing it impractical; context (process, destination rarity, timing) carries the detection.
The defensive lesson is the same in each case: treat a fingerprint as one feature among several and look for disagreement between layers, for example a request claiming to be a desktop browser whose JA4 matches a scripting library, or a TCP fingerprint from a different operating system than the User-Agent claims.
Building allow lists, deny lists and hunts
Allow lists
- Machine-to-machine APIs: partner integrations, internal services and mobile apps usually use a small, stable set of TLS stacks. Baseline the JA4 values seen for each API client over a few weeks, then alert, and later challenge, on new values. Cloudflare's documentation describes this mobile app pattern.
- Locked-down hosts: servers, kiosks and OT gateways that should only run a few applications. The JA3 project describes alerting on any fingerprint outside the expected set in such environments.
- Change process: fingerprints change with library and runtime updates, so tie allow list updates to patch and release pipelines and review new values during change windows rather than after alerts.
Deny lists
- Use only for high-confidence, narrow cases: a fingerprint seen in an active attack against your service, used for a time-limited block or challenge, as both the AWS WAF and Cloudflare documentation describe.
- Check prevalence first: before blocking, count how many distinct clients and how much legitimate traffic share the fingerprint. A value shared by a common runtime will cause an outage.
- Prefer challenge to block on customer-facing services, and set an expiry on every rule.
Hunts
| Hunt | Logic | Related technique |
|---|---|---|
| Rare client fingerprint on a host | JA4 seen on one or few hosts in the estate, first seen recently, to an uncommon destination | T1071.001 Web Protocols |
| Known framework pairing | JA4 and JA4S pair, or JA4X certificate pattern, matching published research on C2 frameworks | T1573.002 Asymmetric Cryptography |
| Process and fingerprint mismatch | EDR shows a browser or Office process, but the JA4 matches a scripting runtime | T1071.001 Web Protocols |
| Layer disagreement on inbound traffic | User-Agent claims a browser; JA4, JA4H or JA4T indicates automation | Bot and account abuse |
| Beaconing with a stable fingerprint | Regular connections with one JA4 to a destination with low prevalence | T1573 Encrypted Channel |
| No SNI to external IPs | JA4 a part with i from user subnets to the internet | T1071.001 Web Protocols |
See the Beaconing and C2 Detection Guide and the Cobalt Strike Abuse Detection Guide for the timing and framework side of these hunts.
Where identity fits
API keys, OAuth client credentials and service account tokens are bearer secrets: whoever holds them can use them. The client that legitimately uses a non-human identity, such as a CI job, an integration or a microservice, normally connects with the same TLS stack every time. Recording the expected JA4 for each high-value machine identity and alerting when that identity's credential is presented from a different fingerprint gives an extra signal for stolen tokens being replayed from attacker infrastructure. It is a signal, not a control: a fingerprint can change with a legitimate update and can be imitated, so pair it with source network restrictions and short-lived credentials. See the Identity Threat Hunting Guide.
Rolling it out
- Collect only. Turn on JA4 (and JA3 where existing content depends on it) at egress sensors and edge services, and send fingerprints with session metadata to the SIEM. Keep raw forms where possible.
- Baseline. Build prevalence tables: fingerprints by host count, by destination and by application. Label the top fingerprints (browsers, update agents, backup tools) so analysts can ignore them.
- Hunt and tune. Run the hunts above weekly, record what each finding turned out to be, and promote stable hunts to scheduled detections.
- Allow lists in monitor mode. For selected APIs and locked-down hosts, alert on new fingerprints for a few weeks before any blocking.
- Enforce narrowly. Move proven allow lists to challenge or block, with a documented rollback (disable the rule or switch the WAF action back to count) and an owner for each list.
- Maintain. Review allow lists after major browser, runtime and library releases, and retire deny list entries on their expiry date.
Detection and measurement
- Coverage: share of egress and inbound TLS sessions that carry a JA4 value.
- Labelled share: share of session volume from fingerprints with a known label; the remainder is the hunting space.
- New fingerprint rate: new JA4 values per week for each allow-listed service, which should spike only around planned releases.
- Hunt yield: fingerprint-led hunts or alerts that led to a confirmed finding, against those closed as benign.
- False block rate: legitimate requests blocked or challenged by fingerprint rules, from support tickets and rule logs.
Framework mapping
| Framework | Reference | How fingerprinting supports it |
|---|---|---|
| MITRE ATT&CK | T1071.001 Web Protocols; T1573 Encrypted Channel; T1573.002 Asymmetric Cryptography | Identifies the client behind encrypted command and control without decryption |
| MITRE D3FEND | D3-NTA Network Traffic Analysis | Fingerprints are a feature of network traffic analysis |
| NIST SP 800-53 Rev 5 | SI-4 System Monitoring; SC-7 Boundary Protection | Monitoring at boundaries; enforcing allow lists at edge services |
| NIST CSF 2.0 | DE.CM-01; DE.AE-02 | Network monitoring for adverse events and analysis of those events |
| CIS Controls v8.1 | Control 13 Network Monitoring and Defense | Network traffic monitoring and alerting |
Common failure patterns
- Treating a hash as a malware verdict. Many malware families use common TLS libraries, so a matching fingerprint without context generates noise and misses variants.
- Staying on JA3 only. With browsers randomising extension order, JA3 produces many values per browser and loses its value as a baseline.
- Blocking a shared fingerprint. A deny rule on a fingerprint used by a popular runtime or HTTP library can block partners, monitoring and mobile apps at once.
- Static allow lists. Lists that are not updated with runtime and library releases cause outages after routine upgrades and get switched off.
- Sensors behind the proxy. Collecting fingerprints after TLS termination records the proxy, not the endpoint.
- Ignoring licence terms. Building JA4+ methods other than JA4 into a commercial product or service without checking the FoxIO licence.
Practitioner checklist
- Enable JA4 at egress sensors before any TLS-terminating proxy and at inbound edge services.
- Keep JA3 only where existing detections depend on it, and plan their migration to JA4.
- Store JA4 raw forms alongside hashes where storage allows.
- Build and label a prevalence baseline before writing any rule.
- Use allow lists for APIs, mobile apps and locked-down hosts; tie their updates to release pipelines.
- Limit deny rules to observed attacks, check prevalence first, prefer challenge, and set expiry dates.
- Correlate fingerprints with process, User-Agent, JA4H, JA4T and destination rarity.
- Record expected fingerprints for high-value machine identities and alert on change.
- Confirm licence terms before embedding JA4+ methods in a product or service.
Standards and references
- FoxIO: JA4 TLS Client Fingerprinting technical details
- FoxIO: JA4+ Network Fingerprinting repository and licensing
- Salesforce: JA3, a method for profiling SSL/TLS clients
- IETF: RFC 8701 Applying GREASE to TLS Extensibility
- OISF: Suricata JA3 and JA4 keywords
- Amazon Web Services: AWS WAF request components
- Cloudflare: JA3 and JA4 fingerprint
Related NHI Mgmt Group resources: NDR Guide · Beaconing and C2 Detection Guide · Bot Management Guide · Encrypted Client Hello Guide · How TLS Works Guide