Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FOR GETTING LAST VERSION OF DATADOME (CHECK/interstitial/INVISIBLE) SOLVER DM ME @yallc

DataDome V5.9.0 Solver

A Go library and CLI tool for generating DataDome browser fingerprints and obtaining valid cookies. Uses Chrome TLS fingerprinting via uTLS to bypass TLS-based bot detection.

Author: yallc

Tracks tags.js version 5.9.0 (ddv=5.9.0). Verified end-to-end: a two-phase solve clears a DataDome-protected /scraping endpoint with HTTP 200 while a bogus cookie on the same path returns 403.


Features

  • Chrome 149 fingerprint generation (~180 signals)
  • 5.9.0 behavioral / biometric eventCounters (mouse-stroke medians, coalesced/predicted pointer stats, session flags)
  • Encrypted jspl payload construction (XOR + dual PRNG keystreams + custom base64)
  • Chrome TLS fingerprint impersonation via uTLS (JA3/JA4 match)
  • HTTP/2 transport with proxy support (HTTP CONNECT / SOCKS)
  • Single-phase and two-phase solve modes
  • Cookie verification against target site (uses same Chrome TLS)
  • XOR integrity checksums (sgb/sgd/sgc) computed correctly inline

Changelog: v5.7.0 → v5.9.0

The jump from 5.7.0 to 5.9.0 is behavioral, not cryptographic. The jspl encryption codec, the TLS transport, and the Chrome-149 fingerprint builder are unchanged; what changed is the eventCounters field that rides alongside the encrypted jspl.

Version tag

v5.7.0 v5.9.0
tags.js version 5.7.0 5.9.0
ddv POST field 5.7.0 5.9.0

eventCounters — flat tally → biometric object

In 5.7.0 the behavioral phase sent a flat count of DOM events:

{"mousemove":87,"pointermove":87,"click":4,"scroll":1,
 "touchstart":0,"touchend":0,"touchmove":0,"keydown":22,"keyup":21}

In 5.9.0 tags.js runs a behavioral analyzer over the real pointer/mouse stream and sends derived statistics instead. Build590EventCounters() reproduces the object with internally-consistent values (ratios derived from the counts) in the ranges a short human session produces:

{"m_s_c":1,"m_m_c":98,"m_c_c":5,"m_cm_r":0.05102,"m_ms_r":98,"m_fmi":895,
 "es_sigmdn":0.0137,"es_mumdn":10.16,"es_distmdn":278.98,"es_angsmdn":0.85,"es_angemdn":1.39,
 "p_fc":97,"m_clsdcnt":355,"p_cf":71,"p_cmx":11,"p_ps":162,"p_pf":54,
 "jset":1785319984,"nddc":1,"exp8":0,"nowd":false,"sfex":false}

New fields

Group Fields Meaning
Mouse counts / ratios m_s_c, m_m_c, m_c_c, m_cm_r, m_ms_r, m_fmi scroll/mousemove/click counts, click÷mousemove and mousemove÷scroll ratios (-1 when the denominator is 0), first-mouse-interaction delay in ms
Mouse-stroke medians (es_*) es_sigmdn, es_mumdn, es_distmdn, es_angsmdn, es_angemdn per-stroke medians: std & mean of log(timeStamp), euclidean stroke distance (px), start & end angle (rad)
Pointer coalesced / predicted (p_*) p_fc, m_clsdcnt, p_cf, p_cmx, p_ps, p_pf stats from getCoalescedEvents() / getPredictedEvents(): frame count, coalesced-event count, coalesced frames, max coalesced per frame, predicted samples & frames
Session flags jset, nddc, exp8, nowd, sfex session start (unix s), navigator flags, no-webdriver / same-frame-exec booleans

The library sends this object automatically in the two-phase behavioral (jsType=le) request; pass -event-counters '{...}' to override it.

Unchanged from 5.7.0 (verified)

  • jspl codec — the PRNG seeds are byte-identical (seedO=1789537805, seedE=9959949970, encryptSeed=1809053797, ivXorConst=11027890091, defaultV=741130091). No re-keying, no format change.
  • TLS transportutls.HelloChrome_Auto for both POST and GET (see the 5.7.0 TLS fix below).
  • Fingerprint builder — the ~180-signal Chrome-149/Win10 payload is carried forward unchanged. tags.js emits the jspl signal object under computed (minified) property names, so no signal-level fingerprint delta is claimed for 5.9.0.

Changelog: v5.6.6 → v5.7.0

Chrome Version

v5.6.6 v5.7.0
Chrome 148 149
UA Chrome/148.0.7778.217 Chrome/149.0.0.0
Full version 148.0.7778.217 149.0.7827.53

Brand String Format Change

v5.6.6: "Not/A)Brand";v="8"
v5.7.0: "Not)A;Brand";v="24"

This affects sec-ch-ua, sec-ch-ua-full-version-list, and the nhi signal.

Signals Removed (5)

Signal Description
cfpjs Canvas fingerprint JS hash
tbce Tab close event listener
rce Reduced color encoding
dfps Device font pixel size
htmlcs HTML charset detection

Signals Added (4)

Signal Description
wwlrv WebWorker language revision
exp8 Experimental flag 8
cdhf CDH fingerprint flag
bbs3 Built-in browser storage v3

Signal Renamed (1)

Old Name New Name Description
vcmku vcmkuts VP9/MKV codec TS flag

Navigation Timing Keys Removed (5)

Signal Description
nt_unt Unload timing
nt_ddi DOM domain interactive
nt_dcl DOM content loaded
nt_rsd Response start delta
nt_dce DOM content end

Feature Flags Removed (3)

Signal Description
mmapi MediaMetadata API
jset2 JS execution time v2
wcsm WebCrypto subtle methods

Browser Check APIs Added (5)

New APIs checked in bchk fingerprint:

API Present in Chrome 149
DetachedViewControlEvent No
SiteBoundCredential No
WebSocketStream Yes
DisplayNames No
SVGDiscardElement Yes

Header Changes

Header v5.6.6 v5.7.0
sec-fetch-site (POST) same-origin cross-site

TLS Fingerprint Fix

v5.7.0 solver uses utls.HelloChrome_Auto for both the POST (cookie creation) and GET (cookie verification) requests. This ensures the TLS fingerprint (JA3/JA4) matches Chrome consistently. Previously, using Go's default net/http for GET requests caused cookie rejection (403) because DataDome binds cookie trust to the TLS fingerprint used during creation.


Install

go install github.com/L0ed0/datadome-solver/cmd/solver@latest

Or build from source:

git clone https://github.com/L0ed0/datadome-solver.git
cd datadome-solver
go build -o solver ./cmd/solver/

CLI Usage

Solve and get cookie

solver -site "https://example.com" -key "YOUR_DDK_KEY" -solve

Solve and verify cookie works

solver -site "https://example.com" -key "YOUR_DDK_KEY" -verify

Two-phase solve (initial + 5.9.0 behavioral)

The behavioral phase automatically ships the 5.9.0 biometric eventCounters:

solver -site "https://example.com" -key "YOUR_DDK_KEY" -two-phase -delay 5

With proxy

solver -site "https://example.com" -key "YOUR_DDK_KEY" -verify -proxy "http://user:pass@proxy:8080"

Override the behavioral counters

solver -site "https://example.com" -key "YOUR_DDK_KEY" -two-phase \
  -event-counters '{"m_s_c":1,"m_m_c":98,"m_c_c":5,"m_cm_r":0.051, ...}'

Dump raw payload as JSON

solver -site "https://example.com" -output payload.json

Print encrypted jspl

solver -site "https://example.com" -key "YOUR_DDK_KEY" -encrypt

Library Usage

package main

import (
    "context"
    "fmt"
    "time"

    "github.com/L0ed0/datadome-solver/pkg/solver"
)

func main() {
    client, err := solver.New("https://example.com",
        solver.WithDDJSKey("YOUR_DDK_KEY"),
        solver.WithProxy("http://proxy:8080"), // optional
    )
    if err != nil {
        panic(err)
    }

    // Two-phase solve: phase 1 (jsType "ch") mints the CID, phase 2 (jsType "le")
    // ships the 5.9.0 behavioral eventCounters. Pass "" to auto-generate them.
    result, err := client.SolveTwoPhase(context.Background(), 5*time.Second, "")
    if err != nil {
        panic(err)
    }
    fmt.Println("Cookie:", result.Cookie)

    // Verify cookie works
    status, body, err := client.Verify(context.Background(), result.Cookie)
    fmt.Printf("Status: %d, Body length: %d\n", status, len(body))
}

Generate the 5.9.0 behavioral counters directly:

counters := solver.Build590EventCounters()

CLI Flags

Flag Default Description
-site Target site URL (required)
-key DataDome JS key (ddk)
-solve false Solve and print cookie
-verify false Solve then verify with GET
-two-phase false Two-phase solve (initial + 5.9.0 behavioral)
-delay 10 Delay between phases (seconds)
-proxy HTTP/SOCKS proxy URL
-profile chrome_win10 Browser profile
-cid Existing CID value
-bpc 1 BPC value
-jstype ch jsType field
-event-counters (empty) Behavioral counters JSON; empty = generate the 5.9.0 biometric set
-encrypt false Print encrypted jspl only
-output Write payload JSON to file
-seed 0 PRNG seed (0 = random)

Architecture

cmd/solver/          CLI entrypoint
pkg/solver/
  client.go          Client, Solve, SolveTwoPhase, Verify, Build590EventCounters
  transport.go       Chrome TLS transport (uTLS + HTTP/2)
internal/
  builder/
    builder.go       Signal payload assembly
    generators.go    Fingerprint generators (bchk, nav timing, checksums)
    profiles.go      Browser profiles (Chrome 149 / Win10)
  crypto/
    crypto.go        jspl encryption (XOR + PRNG + custom base64)

How It Works

  1. Build fingerprint — Generates ~180 browser signals matching Chrome 149 on Windows 10 (screen, WebGL, plugins, codecs, nav timing, error stacks, etc.)
  2. Compute checksums — Calculates XOR integrity checksums (sgb/sgd/sgc) inline during payload construction, ensuring internal consistency
  3. Encrypt — Encodes signals as JSON, XORs with two PRNG keystreams (seeded by DDK + CID + timestamp), encodes with custom base64
  4. Phase 1 (jsType=ch) — POSTs the encrypted jspl to api-js.datadome.co/js/ over a Chrome-impersonated TLS connection (uTLS); the response cookie carries the fresh CID
  5. Phase 2 (jsType=le) — Re-encrypts with bpc=2 under the minted CID and POSTs alongside the 5.9.0 behavioral/biometric eventCounters; the server returns the trusted datadome=... cookie
  6. Verify — Cookie is used for requests to the target site over the same Chrome TLS transport

License

MIT

About

DataDome full reversed — Go library + CLI. uTLS Chrome fingerprint, encrypted jspl payload, behavioral/biometric eventCounters.

Resources

Stars

11 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages