Skip to content

Threat Scoring

WebDecoy uses a sophisticated deception-first scoring system to evaluate every visitor and request. This page explains exactly how scores are calculated, what each category detects, and how to interpret the results.

The Threat Score is a number from 0-100 that measures the likelihood a visitor is automated or malicious. It combines signals from 9 detection categories using weighted averages, with the strongest evidence contributing the most to the final score.

┌─────────────────────────────────────────────────────────────────┐
│ THREAT SCORING PIPELINE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Visitor Request │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ 9 DETECTION CATEGORIES │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │Honeypot │ │ Attack │ │Fingerprnt│ │Behavior │ │ │
│ │ │ 38% │ │ 24% │ │ 11% │ │ 10% │ │ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │
│ │ │ │ │ │ │ │
│ │ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ │ │
│ │ │ TLS │ │ Geo │ │ IP │ │ Headers │ │ │
│ │ │ 7% │ │ 5% │ │ 3% │ │ 1% │ │ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │
│ │ │ │ │ │ │ │
│ │ ┌─────────┐ │ │
│ │ │ User │ │ │
│ │ │Agent 1% │ │ │
│ │ └────┬────┘ │ │
│ └───────┼───────────┼───────────┼───────────┼───────────┘ │
│ │ │ │ │ │
│ └───────────┴─────┬─────┴───────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ WEIGHTED SUM │ │
│ │ = Final Score │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────┐ │
│ │ Threat Score: 0-100 │ │
│ │ + Category Classification │ │
│ │ + Confidence Percentage │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Principle Description
Deception-First Honeypot signals are weighted highest because legitimate users never interact with hidden traps
Weighted Averages Categories are multiplied by their weight, not simply summed
Defense in Depth Multiple signals provide stronger evidence than any single indicator
Low False Positives Easily-spoofed signals (User-Agent, headers) have minimal impact

The scoring calculation follows a simple three-step process:

Each detection category analyzes incoming requests and produces a score from 0-100:

Category Score = Analysis of signals within that category
(0 = no suspicious signals, 100 = maximum suspicion)

Each category score is multiplied by its weight percentage:

Weighted Score = Category Score × Weight Percentage

All weighted scores are summed to produce the final Threat Score:

Final Score = Sum of all Weighted Scores

Consider a visitor who triggered some honeypot signals and has suspicious headers:

Category Raw Score Weight Weighted Score
Honeypot Signals 30 × 38% = 11.4
Attack Signatures 0 × 24% = 0
Browser Fingerprint 0 × 11% = 0
Behavioral Analysis 0 × 10% = 0
TLS Fingerprint 0 × 7% = 0
Geo Consistency 0 × 5% = 0
IP Reputation 0 × 3% = 0
HTTP Headers 15 × 1% = 0.15
User Agent 0 × 1% = 0
Total: 12

Result: This visitor receives a Threat Score of 12 (Minimal risk).


Categories are weighted by reliability. High-confidence signals like honeypot triggers contribute more than easily-spoofed signals like User-Agent strings.

Priority Category Weight Why This Weight
Highest Honeypot Signals 38% Core deception signal - legitimate users never trigger these
High Attack Signatures 24% Active exploitation attempts are clear malicious intent
Medium Browser Fingerprint 11% Automation tools have detectable anomalies
Medium Behavioral Analysis 10% Non-human patterns are reliable indicators
Medium TLS Fingerprint 7% JA3/JA4 fingerprints are hard to spoof
Low Geo Consistency 5% Timezone, language and WebRTC mismatches indicate VPN or proxy
Low IP Reputation 3% High false-positive potential (VPN users)
Low HTTP Headers 1% Easily spoofed by sophisticated bots
Low User Agent 1% Trivially spoofed, catches only obvious cases
Honeypot Signals ██████████████████████████████████████ 38%
Attack Signatures ████████████████████████ 24%
Browser Fingerprint ███████████ 11%
Behavioral Analysis ██████████ 10%
TLS Fingerprint ███████ 7%
Geo Consistency █████ 5%
IP Reputation ███ 3%
HTTP Headers █ 1%
User Agent █ 1%
─────────────────────────────────────────
0% 25% 50% 75% 100%

Priority: Highest

Detects visitors who access hidden decoy links, fill invisible form fields, or interact with trap endpoints.

Signal Type Description Score Impact
Hidden field filled Invisible form field populated (reported by the Detection Script) +40
Hidden link clicked Hidden link followed (reported by the Detection Script) +40
Decoy link or decoy endpoint accessed Trap resource fetched +30
SDK tripwire hit Hidden tripwire path requested +40

Points add up within the component, which is capped at 100.

Why it matters: Legitimate users never see or interact with these hidden elements. A trigger here is strong evidence of automated scanning or malicious reconnaissance. This is the cornerstone of WebDecoy’s deception-first approach.

The hidden-field and hidden-link signals are reported by the browser-side Detection Script. A server-side trap (a decoy or tripwire) is a different shape of evidence: somebody fetched a hidden URL, ran no JavaScript, and reported nothing. Those hits score on this component in their own right.

This matters more categorically than numerically. Any honeypot score at or above 20 classifies the visitor as a scanner, so a client that reached a hidden resource is never filed as legitimate again, however clean the rest of its request looks. A detection that both fetched a decoy and reported a client-side trigger is counted once, not twice.

Sources that are not deception (the edge sensor, the detection script’s own beacon, ordinary SDK traffic) contribute nothing to this component.


Priority: High

Identifies known attack patterns in request payloads including injection attempts and exploitation techniques.

Attack Type Pattern Examples Score Impact
SQL Injection ' OR '1'='1, UNION SELECT, ; DROP TABLE +50
Command Injection ; cat /etc/passwd, ` ls -la, `` whoami` ``
Cross-site Scripting (XSS) <script>, javascript:, onerror= +40
Path Traversal ../../../etc/passwd +50
Mass Assignment Privilege fields such as is_admin in a JSON body +45
XXE <!DOCTYPE with <!ENTITY, SYSTEM "file: in an XML body +55
PHP / Java deserialization Serialized PHP objects, rO0AB Java streams +60

Each additional attack type in the same request adds +20. The component is capped at 100.

Why it matters: These are direct indicators of malicious intent. These patterns are rarely seen in legitimate traffic and represent active exploitation attempts.

Example Detection:

POST /api/users/login HTTP/1.1
Content-Type: application/json
{"email": "[email protected]", "password": "' OR '1'='1' --"}
→ Attack Signature Score: 50 (SQL Injection detected)

Priority: Medium

Analyzes client-side fingerprinting data to detect headless browsers, automation tools, or spoofed environments.

Signal Detection Method Score Impact
WebDriver detected navigator.webdriver = true +65
Automation framework Puppeteer, Playwright or Selenium markers +60
Headless browser markers Chrome headless signatures (desktop only) +45 to +60
CDP artifacts Chrome DevTools Protocol markers +50
Canvas anomaly Canvas fingerprint doesn’t match browser +35
WebGL anomaly GPU fingerprint mismatch +30
Software renderer SwiftShader and similar (also common on VMs) +25
Plugin anomaly Plugin configuration inconsistent (desktop only) +25
No plugins Empty plugins list (desktop only) +10
Lie/tampering Native functions modified by stealth plugins +8 each, +30 max
Mocked audio Mocked or zeroed AudioContext +15 to +20

AI browser extension flags also score here; see AI Detections.

Why it matters: Automation tools often have telltale fingerprint anomalies that are difficult to fake convincingly. While sophisticated bots can spoof some signals, maintaining consistent fingerprints across all dimensions is challenging.

Example Detection:

// Detected anomalies:
navigator.webdriver = true // WebDriver flag set
navigator.plugins.length = 0 // No plugins (unusual)
window.cdc_adoQpoasnfa76pfcZLmcfl_Array // ChromeDriver CDP artifact
→ Fingerprint Score: 100 (capped)

Priority: Medium

Examines interaction patterns including mouse movements, keyboard input, scroll behavior, and navigation timing.

Signal What It Detects Score Impact
Ghost clicks Clicks at positions with no prior mouse activity +45
Instant clicks Clicks with no delay after the mouse stops +30
Low mouse count Very few mouse movements on desktop +25
Linear mouse paths Perfectly straight mouse paths +20
Clicks without movement Clicks with no preceding mouse movement +20
Constant mouse velocity No human acceleration +15
Instant mouse movements Programmatic cursor jumps +15
Constant scroll speed Robotic scrolling (desktop only) +15
Grid-aligned mouse Movements aligned to a grid +10

Mouse, click and scroll signals are skipped on mobile devices.

Why it matters: Bots typically exhibit non-human behavior patterns: too fast, too uniform, or missing expected interactions. Real humans have micro-movements, variable timing, and natural browsing patterns that are difficult to simulate perfectly.

Example Detection:

Session Analysis (illustrative):
├── Mouse movements: 2 on desktop → low mouse count +25
├── Click with no prior movement → ghost click +45
└── Mouse path perfectly straight → linear path +20
→ Behavior Score: 90

Priority: Medium

Uses JA3/JA4 fingerprinting to identify the TLS client implementation and match against known automation tools.

TLS Signal What It Indicates Score Impact
Minimal cipher suite Far fewer ciphers than any browser offers +50
Low cipher count Fewer ciphers than a browser +25
Minimal TLS extensions Almost no extensions +40
Low extension count Fewer extensions than a browser +20
JA3 with no extensions Extension list empty +30
Known VPN/proxy fingerprint Handshake matches a known VPN or proxy client +25
Low signature algorithm count Typical of automation libraries +20
Browser UA without h2 ALPN Claims a modern browser but does not offer HTTP/2 +15

Why it matters: TLS fingerprints are generated at the protocol level before any application code runs, so a handshake that offers far less than a browser does gives away a script even when the User-Agent claims a browser. The JA3 and JA4 fingerprints are recorded on the detection; JA4 is the value WAF rules key on.


Priority: Low

Cross-checks what the browser says about itself against where the connection appears to come from.

Signal What It Detects Score Impact
WebRTC address mismatch Real address differs from the connection address +30
Timezone mismatch Browser timezone contradicts IP geolocation +20
Language mismatch Browser language contradicts the country +15
Composite VPN likelihood Several geo signals agreeing +10

Why it matters: These are the signals that survive a good proxy. A scraper can route through a residential exit node and still be running on a machine set to a different timezone with a different locale. The weight is low on purpose, because privacy-conscious real people trip these constantly.


Priority: Low

Checks IP addresses against threat intelligence feeds and identifies datacenter/proxy/VPN connections.

Signal Source Score Impact
AbuseIPDB abuse confidence AbuseIPDB Scaled from the confidence score
Abuse report count AbuseIPDB Scaled from the number of reports
TOR exit node GeoIP / VPN detection +45
Open proxy GeoIP / VPN detection +30
VPN service GeoIP / VPN detection +25
Datacenter hosting IP belongs to a hosting provider +20
Anonymous IP Flagged as an anonymity service +20
Privacy relay iCloud Private Relay, WARP and similar +15
Many user agents on one IP Distinct user agents from the address in 24h Scaled
Impossible travel Same client seen too far apart too quickly Scaled

Why it matters: Provides useful context but has high false-positive potential. Many legitimate users use VPNs for privacy, and datacenter IPs might be corporate proxies. That’s why this category only contributes 3% to the final score.


Priority: Low

Analyzes HTTP request headers for missing standard headers or patterns associated with automated tools.

Signal What’s Detected Score Impact
Missing standard headers Accept, Accept-Language, Accept-Encoding and similar +10 each
No Referer Direct access to deep pages +15
Text-only Accept Asks for text content only, no images +15
Missing Sec-Fetch-* Modern browser UA without Sec-Fetch headers Scaled
Missing Client Hints Chrome 89+ UA without Client Hints +12
Sec-CH-UA without GREASE Spoofed Client Hints +10
Accept-Language without quality values Real browsers send ;q= weights +8
Missing Priority header Chrome 119+ UA without it +6
Generic Accept */* +5
No cookies Stateless client or first visit +5
Connection: close Uncommon for browsers +5

Why it matters: Simple bots often omit headers that real browsers include automatically. However, this is easily spoofed by adding the expected headers, which is why the weight is low.

Example:

GET /api/data HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0...
# Missing: Accept, Accept-Language, Accept-Encoding, Cookie, Referer
→ Several header signals fire (missing headers, no cookies, no Referer)

Priority: Low

Examines User-Agent strings for bot signatures, outdated versions, or obvious automation markers.

A catalogued agent is scored by the registry

Section titled “A catalogued agent is scored by the registry”

If the User-Agent matches an agent in WebDecoy’s shared agent registry, this component takes the registry’s base score for that agent. It does not guess from how the name is spelled.

That distinction turned out to matter a great deal. The old heuristic returned 100 for any User-Agent containing the substring bot, which meant:

Agent Registry base Old heuristic score Why
ChatGPT-User 85 100 Matched bot inside +https://openai.com/bot, the courtesy URL a crawler publishes so it can be identified
ByteSpider 75 35 Contains no bot anywhere, so it fell through to the generic suspicious-UA rule

ByteSpider, the only one of those two that ignores robots.txt, was scoring roughly half its base while agents whose names happen to contain “bot” landed near theirs. Catalogued agents now sit in the order the registry assigns rather than the order their names are spelled.

Agents the registry has never heard of keep the older heuristics below, because that fallback is still the right answer for a self-identifying tool nobody has catalogued yet.

Signal Examples Score Impact
Catalogued agent GPTBot, ByteSpider, Googlebot, curl, python-requests The registry’s base score for that agent
Uncatalogued bot or tool UA Self-identifying tools nobody has catalogued Heuristic, up to 100
Empty User-Agent No UA provided +25
Outdated browser Chrome or Firefox many versions behind +15 to +70
Chromium UA with no client hints Claims Chrome, sent no Sec-CH-UA +50
Browser UA that never rendered A request-log visit fetched pages but none of their scripts or styles +45
Browser UA that read crawler files The same visit also asked for robots.txt, a sitemap, ads.txt or security.txt +30

The last two rows come only from sources that log every request your site answers: the Vercel log drain and Fastly log streaming. A browser that opens a page goes on to fetch the page’s own scripts and styles. A scraper that copies a browser’s user agent takes the HTML and leaves.

Logs arrive in small deliveries, often a few requests at a time, so a page and the scripts its browser fetched a second later usually arrive separately. WebDecoy holds each browser-like page request for 45 seconds, then checks whether that browser (same site, address and user agent) fetched any of the site’s render assets. Render assets are /_next/static/ files, ?_rsc= payloads, /_next/data/, Vercel Analytics beacons, and same-site .js, .css and web fonts. Images, Open Graph cards and favicons do not count, because link-preview bots fetch those too.

That evidence is kept for 30 days as a keyed hash of the site, address and user agent, never the address itself, so every server handling your logs sees the same answer. Nothing else about the request is kept.

It is deliberately cautious:

  • A browser that rendered at any point in the last 30 days is not flagged, so a returning visitor whose assets come from cache is not mistaken for a scraper. A visitor whose last rendered visit was longer ago than that, with every asset still cached, can be; those reports score MINIMAL.
  • A page is left undecided, never flagged, when we have not recently seen your site serve render assets (asset logging may be off) or when the evidence cannot be read.
  • One report per browser per site per 30 minutes, however many pages it reads.
  • A person who opens robots.txt by hand after reading the site is not flagged, because they rendered.

Visits that rendered are not reported or stored. A scraper that runs a full headless browser fetches the assets too and passes this check; the other signals on this page are still there for it.

An unverified claim may not profit from the identity it claims

Section titled “An unverified claim may not profit from the identity it claims”

Granting every catalogued agent its base score has an obvious hole: 44 registry agents carry a base of 40 or less and publish no IP ranges anyone can check. Slackbot, Twitterbot, Discordbot, WhatsApp, TelegramBot, LinkedInBot, UptimeRobot, Pingdom, the Wayback Machine, YandexBot, Baiduspider, Yahoo! Slurp and Sogou are all in that set. For every one of them, simply claiming the identity would buy a low score.

Verification is what separates the two cases, so it does:

  • A verified agent is scored exactly as the registry says.
  • An unverified claim gets the worse of the registry base and the heuristic.

It can never be cheaper to claim an identity than to arrive without one. The rule only ever raises a score, so the registry fix survives intact: ByteSpider is unverified with a base of 75 against a heuristic of 35, and keeps the 75.

The major search engines were never exposed to this, because Googlebot, Bingbot, DuckDuckBot and Applebot all publish IP ranges, so a spoofed one hits the impersonation floor long before it reaches this rule. The gap was entirely in the crawlers that publish nothing, which is also where it is hardest to notice.

Why it matters: User-Agent is trivially spoofed by any bot, so it receives minimal weight (1%). It only catches the most obvious, unsophisticated bots that don’t bother to set a realistic User-Agent, plus the ones that catalogue themselves honestly.


Scores are grouped into five threat levels for easier interpretation and action.

Score Range Level Confidence needed Description Recommended Action
0-20 MINIMAL none Very low risk, likely legitimate Allow
21-40 LOW none Some signals, probably benign Log
41-60 MEDIUM 30% Suspicious activity detected Monitor/Challenge
61-80 HIGH 50% Strong bot/malicious indicators Challenge/Block
81-100 CRITICAL 70% Almost certainly automated/malicious Block

The level is gated by confidence as well as score. A detection scoring 90 on signals the scorer is only 40% confident in is reported as MEDIUM, not CRITICAL: the number says how much evidence there is, and the level says how much of it we would stand behind.

The recommended actions are guidance for your own policy. WebDecoy does not block or challenge a request because of its level: that is decided by your protected paths, response actions and SDK or plugin mode (Monitor by default).

Score: 12 | Level: MINIMAL | ● Green

Characteristics:

  • Few or no suspicious signals detected
  • Normal browsing patterns observed
  • Standard browser fingerprint
  • Good IP reputation

Interpretation: This is normal, legitimate traffic. The visitor behaves like a real human using a standard browser.

Recommended Actions:

  • Allow the request
  • No special logging required
  • No alerts needed

Score: 35 | Level: LOW | ● Lime

Characteristics:

  • Minor signals present (e.g., VPN usage, missing header)
  • No honeypot triggers
  • Mostly normal behavior patterns
  • Could be privacy-conscious user or minor automation

Interpretation: Some signals are present but likely benign. Could be a legitimate user with a VPN or unusual browser configuration.

Recommended Actions:

  • Allow the request
  • Log for pattern analysis
  • Monitor for escalation

Score: 52 | Level: MEDIUM | ● Yellow

Characteristics:

  • Multiple suspicious signals
  • Possible fingerprint anomalies
  • Unusual behavior patterns
  • May have triggered low-weight honeypots

Interpretation: Suspicious activity that warrants attention. Could be a scanner, scraper, or unsophisticated bot.

Recommended Actions:

  • Consider CAPTCHA challenge
  • Log with high priority
  • Alert on repeated occurrences
  • Manual review recommended

Score: 73 | Level: HIGH | ● Orange

Characteristics:

  • Strong indicators of automation
  • Likely honeypot triggers
  • Fingerprint clearly indicates bot/headless browser
  • Suspicious or malicious patterns

Interpretation: Almost certainly not a legitimate human user. This is likely a bot, scanner, or attacker.

Recommended Actions:

  • Challenge or block
  • Alert security team
  • Add IP to watchlist
  • Investigate the attack pattern

Score: 92 | Level: CRITICAL | ● Red

Characteristics:

  • Multiple high-confidence indicators
  • Attack signatures detected
  • Honeypot(s) triggered
  • Clear malicious intent

Interpretation: This is definitely automated or malicious traffic. Active attack or aggressive scanning in progress.

Recommended Actions:

  • Block immediately
  • Alert security team
  • Consider IP blocking at edge
  • Investigate and document
  • Report to threat intelligence if applicable

Beyond the numeric score, visitors are classified into categories based on which signals triggered.

Categories are determined by evaluating signals in priority order:

1. Attack Signatures ≥ 30 → ATTACKER
2. Honeypot ≥ 40 AND Fingerprint ≥ 30 → BOT
3. Honeypot ≥ 20 → SCANNER
4. The agent registry names this agent's kind → that kind
5. User Agent ≥ 90 → SCANNER
6. User Agent ≥ 60 → CRAWLER
7. Fingerprint ≥ 40 AND confidence ≥ 30% → SCRAPER
8. User Agent ≥ 30 OR Headers ≥ 25 → SCRAPER
9. Default → LEGITIMATE

The ordering is the design: evidence of what the request did (attack signatures, honeypot trips) beats identity (the registry’s answer for a named agent) beats inference (a kind guessed from the size of an anomaly score).

Category Icon Triggers Description
Attacker ⚠️ Attack signatures (SQLi, XSS, etc.) Active exploitation attempts
Bot 🤖 Honeypot + fingerprint anomalies Automated traffic with technical non-human signs
Scanner 📡 Any honeypot/decoy trigger Reconnaissance or vulnerability scanning
Crawler 🕷️ Known crawler User-Agent Web crawlers and indexing bots
Scraper 📋 Fingerprint anomalies (no honeypot) Content scraping or data harvesting
Legitimate ✓ All signals below threshold Normal human visitor

Attacker:

Request: POST /api/login
Body: {"password": "' OR '1'='1"}
Attack Signature Score: 50
→ Category: ATTACKER

Bot:

Clicked a hidden link, then fetched /admin/backup.zip (decoy)
Fingerprint: WebDriver=true, no plugins
Honeypot Score: 70, Fingerprint Score: 75
→ Category: BOT

Scanner:

Accessed: /.git/config (decoy)
Normal fingerprint otherwise
Honeypot Score: 30
→ Category: SCANNER

Legitimate:

Normal browsing pattern
No honeypots triggered
All signals < thresholds
→ Category: LEGITIMATE

The Confidence percentage indicates how certain WebDecoy is about the threat assessment.

Confidence is based on the number and quality of active signals:

Factor Impact
More signal categories active Higher confidence
Attack signature at 50 or above +30% confidence boost
Honeypot at 60 or above +25% confidence boost
Fingerprint at 50 or above and at least one reliable automation flag +20% confidence boost
Only 1-2 weak signals Lower confidence
Base Confidence = (Active Categories / 9) × 100
Adjustments:
+ 30% if attack signature score ≥ 50
+ 25% if honeypot score ≥ 60
+ 20% if fingerprint score ≥ 50 AND a reliable fingerprint flag fired
Confidence Meaning Action
80-100% Very certain Act on the score
60-79% Reasonably certain Act with monitoring
40-59% Moderate certainty Consider challenging
20-39% Low certainty Log and observe
0-19% Very uncertain Collect more data

Verified identity changes what the numbers mean

Section titled “Verified identity changes what the numbers mean”

The categories above measure how automated and how evasive a client looks. A verified identity (a match against the crawler’s published IP ranges, a forward-confirmed reverse DNS record, or a Web Bot Auth signature) answers both of those questions at once: a verified crawler is exactly as automated as it says it is, and hiding is the one thing it is not doing.

Two rules follow from that, and both were shipped after production data showed the scorer treating large legitimate crawler fleets as adversaries.

Rotation does not escalate a verified agent

Section titled “Rotation does not escalate a verified agent”

A crawler fleet is one identity operating from many addresses by design. Before this rule, the rotation bonus escalated range-verified Bingbot and ChatGPT-User fetching ordinary pages into HIGH and CRITICAL.

The escalation is now skipped when the scorer confirmed the claimed identity. Spoofed and unverified claims still escalate, so a forged Googlebot arriving from residential ranges keeps scoring at the top. If a rotation bonus was recorded before verification resolved, it is dropped when the detection is rescored rather than carried forward.

A verified agent is capped at the top of MEDIUM

Section titled “A verified agent is capped at the top of MEDIUM”

Even without the rotation bonus, verified agents kept landing in HIGH on anomaly evidence alone. Bingbot’s own renderer scored 91 and above, because its Chromium honestly reports navigator.webdriver and its fleet trips every datacenter, VPN and spoofed-UA heuristic there is. Verified PerplexityBot and GPTBot page reads sat at 74 to 75.

A detection whose identity verified is now capped at 60, the top of the MEDIUM band, applied after every score contribution including the client-side blend, so nothing downstream re-inflates it. The cap records itself as a signal carrying the pre-cap score, so the breakdown still shows what the anomaly tiers saw and why the ceiling applied.

Hostile acts bypass the ceiling. A honeypot trip or an attack signature is evidence of what the request did, not of what the client is, and a verified agent in a decoy is a real event whatever its identity. Spoofed and unverified claims are untouched.


WebDecoy has no score-threshold block setting. If you act on scores yourself (for example from a webhook or your own middleware), these are reasonable starting points:

Use Case Block Threshold Challenge Threshold
Financial / Banking 55 40
E-commerce 65 50
Standard Websites 75 60
Public Content / Blogs 85 70
Monitoring Only N/A (log only) N/A
function handleRequest(detection) {
// Field names from the detection API; confidence is 0 to 1
const { unified_score: score, confidence, threat_category: category } = detection;
// Critical threats - block immediately
if (score >= 80 && confidence >= 0.6) {
return blockRequest();
}
// High threats - challenge or block
if (score >= 60) {
if (category === 'attacker') {
return blockRequest();
}
return challengeWithCaptcha();
}
// Medium threats - log and monitor
if (score >= 40) {
logHighPriority(detection);
return allowWithMonitoring();
}
// Low/Minimal threats - allow
return allowRequest();
}

Use category filters in the Detections table to focus on specific threat types:

  • Attackers first: select Attacker in the Threat Category panel to investigate active exploitation attempts
  • Scanner review: select Scanner to see what reconnaissance activity is happening
  • Legitimate verification: select Legitimate with a high minimum threat score to find potential false positives

Reducing False Positives:

  1. Raise the threshold your own logic blocks at (e.g., 75 → 85)
  2. Rely on verified identity: good bots (Googlebot, Bingbot) are verified by IP, and a verified agent is capped at 60
  3. Review medium-score detections manually, and mark wrong ones Not a bot

Catching More Threats:

  1. Lower the threshold your own logic blocks at (e.g., 75 → 65)
  2. Add more decoy links to pages
  3. Install the Detection Script for JavaScript and behavioral analysis
  4. Monitor category distribution for patterns

Everything above describes the system in general. To see why one particular detection scored what it did, open it in the dashboard: the detection detail flyout carries a Threat Score Breakdown built from the per-signal attribution the scorer recorded at the time.

Each contributing signal is listed with its name, the points it added, the ceiling for that signal, a bar, and the description the scorer wrote for it:

Threat score: High 87 / 100
Honeypot path hit +40
Datacenter IP, no rDNS +22 of 25
Header order ≠ claimed UA +15 of 20

Three things about that display are deliberate:

  • The parts do not sum to the whole, and the panel says so. Categories are weighted and capped, so printing 40 + 22 + 15 = 87 would be arithmetic that fails the first time anyone checks it. The listed points are what moved the score, largest first.
  • The ceiling is only printed when the signal did not reach it. Most signals contribute a fixed amount and therefore sit at their own ceiling by definition, so “+40 of 40” is noise on every line. “+10 of 30” says something: this one was dialled down and could have been worse.
  • Bars compare signals to each other, not to 100. A bar scaled to an absolute maximum drew the largest contributor half full while a signal worth half as much drew a whole one, which ranked the picture in the opposite order to the numbers beside it.

Signals that scored zero are dropped from the list, because twelve “+0” rows under a score of 87 bury the four that produced it. The radar chart alongside is where “we looked at this category and saw nothing” belongs.

Confidence is stated in prose, and only when it is low enough to qualify the score.

A How scoring works link at the foot of the breakdown opens the general explainer, which is what this page describes.