Seatext library / BotRefund evidence
How to Implement Corroboration in a Bot Detection System
Corroboration means collecting each bot signal independently, normalizing its output, weighting signals by reliability, defining a clear decision rule, and continuously monitoring where signals disagree. This multi-signal approach replaces single-check verdicts with a pattern...
✓ Built for advertisers who need clear, refund-ready traffic evidence.
To implement corroboration in a bot detection system, start by collecting each signal independently so no single check can veto a session. Normalize every signal to a common scale, then weight them according to how reliably each distinguishes humans from automation in your traffic. Define a decision rule that combines weighted scores into a final classification, and instrument monitoring that flags when signals disagree so you can retrain weights without guessing.
What corroboration means in bot detection
Corroboration is the practice of treating every detection signal as independent evidence rather than a standalone verdict. A single anomaly — such as a WebGL texture mismatch or an unexpected port — can appear for legitimate reasons: privacy extensions, corporate proxies, travel, or uncommon hardware. BotRefund describes this explicitly: "A single anomaly is not a bot verdict. Privacy tools, travel, corporate networks, and unusual devices can produce unexpected behavior for genuine people." (S1)
Instead of blocking on one tell, a corroboration engine gathers dozens of independent checks — browser fingerprinting, network attributes, behavioral patterns, device characteristics — and evaluates how they fit together. The goal is a coherent picture where multiple signals either reinforce or contradict each other.
Core signals to collect independently
Build a signal inventory that spans four categories. Each category should contain multiple checks that fail for different reasons.
- Browser and device fingerprinting: WebGL texture constraints, canvas rendering, font enumeration, audio context, JS engine quirks, hardware concurrency, battery API, screen properties.
- Network and geolocation: IP reputation, ASN type, suspicious ports, timezone vs. language mismatch, VPN/proxy indicators, TLS fingerprint.
- Behavioral patterns: Mouse tremor, click timing, scroll velocity, form interaction speed, navigation path entropy, session duration distribution.
- Challenge responses: Honeypot interactions, CAPTCHA solve patterns, iframe blocking behavior, cookie persistence.
BotRefund runs 106 independent checks across these categories, including WebGL Texture Constraint and Suspicious Ports, each producing its own evidence object. (S1; S7)
Normalizing and weighting signals
Each signal emits a raw value — boolean, numeric, categorical. Convert every output to a normalized score between 0 (strongly human) and 1 (strongly automated). For boolean checks, map pass to 0 and fail to 1. For continuous measures (e.g., mouse tremor variance), fit a calibration curve on labeled traffic.
Assign weights based on empirical false-positive and false-negative rates measured on your own traffic. A signal that rarely fires on humans but often fires on bots gets a high weight. A signal that fires frequently on both gets a low weight. BotRefund's approach: "This signal adds one objective fact about the visit... BotRefund tests whether other signals support the same story... Our model weighs the complete pattern instead of trusting a raw rule." (S1)
Store weights in a versioned configuration so you can roll back or A/B test new weight sets without code changes.
Building the decision rule
Combine weighted scores into a single session risk score. Common approaches:
- Weighted sum: risk = Σ (weight_i × score_i). Threshold the sum.
- Logistic regression: train a lightweight model on labeled sessions; coefficients become weights.
- Gradient-boosted trees: capture non-linear interactions between signals (e.g., WebGL mismatch + suspicious port is worse than either alone).
Define three zones: allow (score < low threshold), challenge (between thresholds), block (score > high threshold). The challenge zone lets you collect more evidence (CAPTCHA, device attestation) before final disposition.
BotRefund feeds all signals into a prediction AI that "evaluates the complete picture across browser, network, device, and behavior evidence" and claims 99% accuracy through this pattern. (S1)
Monitoring signal disagreement over time
Corroboration degrades silently when new browser versions, privacy tools, or bot frameworks shift signal distributions. Instrument these monitors:
- Pairwise disagreement rate: for each signal pair, track how often one says human while the other says bot. Rising disagreement flags a drifting signal.
- Signal contribution drift: measure each signal's average weight × score in allowed vs. blocked sessions. A signal that stops separating the populations needs recalibration.
- False-positive sampling: periodically review a random sample of blocked sessions with manual review or downstream conversion data (e.g., did the user later complete a purchase?).
- Versioned signal registry: every signal change (new check, retired check, weight update) gets a version tag. Rollback is a config deploy.
Common implementation mistakes
- Treating a strong signal as a veto: blocking on WebGL mismatch alone catches privacy users. Keep every signal advisory.
- Static weights: weights calibrated at launch become stale within weeks as browser updates roll out.
- No challenge zone: binary allow/block forces you to choose between false positives and false negatives.
- Ignoring correlation: two signals that always fire together (e.g., headless Chrome + missing battery API) should not count as independent evidence.
- No feedback loop: without conversion or manual-review labels, you cannot measure whether the decision rule improves.
Verification and testing approach
- Shadow mode: run the corroboration engine in parallel with existing rules. Log every session's signal vector, weighted score, and final decision without enforcing.
- Backtest on labeled data: apply the engine to the last 30 days of sessions with known outcomes (chargebacks, conversion, manual review). Measure precision, recall, and AUC.
- A/B ramp: enable enforcement for 1% of traffic, compare conversion rate and dispute rate against control. Increase gradually.
- Disagreement audit: weekly, pull the top 50 sessions where signals disagreed most. Label them manually. Use labels to retrain weights.
Key facts
| Fact | Detail | Source |
|---|---|---|
| Independent checks per session | 106 | S1 |
| Signal treatment | Each signal kept as evidence, not a verdict | S1 |
| Cross-check principle | BotRefund tests whether other signals support the same story | S1 |
| Decision model | AI prediction weighs complete pattern across browser, network, device, behavior | S1 |
| Claimed accuracy | 99% via corroboration, not single tells | S1 |
| Legitimate anomaly sources | Privacy tools, travel, corporate networks, unusual devices | S1 |
| Behavioral signal categories | Click, pointer, motion, speed, path, engagement, session | S2 |
| Network signal example | Suspicious Ports check for proxy rotation and location masking | S7 |
Limitations and when this advice does not apply
- Low-traffic sites: insufficient labeled data to calibrate weights or train a model. Start with a managed service that pools cross-customer data.
- Real-time hard-block requirements: if you must block at the edge within milliseconds, a heavy corroboration pipeline may add latency. Use a lightweight rule set at the edge and async corroboration for logging.
- Regulated environments: some jurisdictions restrict fingerprinting. Verify legal basis before deploying browser/device signals.
- Single-page apps with no navigation: behavioral signals (scroll, path, session duration) weaken; rely more on fingerprint and challenge signals.
FAQ
How many signals do I need to start?
Start with 8–12 diverse signals covering at least three categories (fingerprint, network, behavior). Fewer signals leave you vulnerable to single-point evasion; more signals increase maintenance without proportional gain until you have volume to weight them.
What is a good weight calibration method?
Use logistic regression on a labeled dataset (minimum 5,000 sessions with known human/bot labels). Coefficients become initial weights. Re-train weekly with fresh labels.
How do I handle signals that correlate?
Compute pairwise correlation on allowed traffic. If two signals correlate > 0.8, merge them into a composite signal or down-weight one. Independence is the assumption behind weighted summation.
When should I use a challenge instead of block?
Use challenge for scores in the middle 40–60th percentile of your risk distribution. Challenges (CAPTCHA, device attestance, email verification) convert ambiguous sessions into labeled data for future weight updates.
How do I measure if corroboration is working?
Track three metrics: (1) false-positive rate on converting users, (2) bot catch rate measured by downstream fraud signals (chargebacks, fake leads), (3) signal disagreement trend. All three should improve or hold steady over 30-day windows.
Can I implement corroboration without ML?
Yes. A weighted sum with manually tuned weights and a three-zone threshold is a valid corroboration engine. ML helps when signal interactions are non-linear, but a transparent rule set is easier to audit and debug.
What data do I need to label sessions for training?
Minimum: session ID, timestamp, signal vector, and a ground-truth label (human/bot). Labels come from chargebacks, CRM conversion, manual review, or honeypot conversions. Aim for at least 1,000 labeled bots and 10,000 labeled humans before first training.
Further reading and comparison sources
These external sources provide additional context for evaluating the topic. Their inclusion is not an endorsement.
Learn more
Visit the website for more information.