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
Decoy link access Hidden link followed +60-90
Hidden field filled Invisible form field populated +50-80
Fake API endpoint hit Trap endpoint accessed +70-95
Trap path accessed Honeypot URL visited +65-90
Multiple honeypots triggered Several traps hit +85-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 signals in the table above are reported by the browser-side Detection Script. A server-side trap is a different shape of evidence: somebody fetched a hidden URL, ran no JavaScript, and reported nothing.

Those hits now score on this component in their own right:

Trap Contribution
Decoy link or decoy endpoint accessed +30
SDK tripwire hit +40

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 +70-90
Cross-site Scripting (XSS) <script>, javascript:, onerror= +60-85
Command Injection ; cat /etc/passwd, ` ls -la, `` whoami` ``
Path Traversal ../../../etc/passwd, ....//....// +55-75
XXE <!ENTITY xxe SYSTEM, file:///etc/ +70-90
LDAP Injection )(cn=*, `)(uid=))( (uid=*`
NoSQL Injection {"$gt": ""}, {"$ne": null} +60-80

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: 85 (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 +60-80
Missing plugins No plugins array or empty +30-50
Canvas anomaly Canvas fingerprint doesn’t match browser +40-60
Headless browser markers Chrome headless signatures +55-75
WebGL inconsistency GPU fingerprint mismatch +35-55
Timezone mismatch Browser timezone vs IP geolocation +25-40
Language mismatch Browser language vs expected +20-35
CDP artifacts ChromeDriver cdc_ properties, Selenium evaluation markers +70-90
Lie/tampering Native function toString() modified (stealth plugins) +45 max
Worker mismatch Main thread vs Web Worker navigator differs +40 max
Canvas pixel noise Anti-fingerprinting noise in canvas output +30

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)
canvas.toDataURL() = [headless hash] // Known headless signature
window.cdc_adoQpoasnfa76pfcZLmcfl_Array // ChromeDriver CDP artifact
Fingerprint Score: 82

Priority: Medium

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

Signal What It Detects Score Impact
No mouse movement Zero cursor events recorded +40-60
Impossible timing Actions faster than human capability +50-70
Linear navigation Perfectly straight mouse paths +35-50
Missing scroll events No scrolling on long pages +25-40
Instant form submission Form submitted in <500ms +45-65
No keyboard patterns Keys pressed without natural rhythm +30-45
Robotic click patterns Clicks at exact same coordinates +40-55

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:
├── Mouse events: 0 (expected: 50-200 for page complexity)
├── Time on page: 0.3s (submitted form)
├── Scroll depth: 0% (form below fold)
└── Keyboard rhythm: N/A (no typing detected)
→ Behavior Score: 68

Priority: Medium

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

TLS Signature What It Indicates Score Impact
Known bot signature Matches scrapy, selenium, etc. +50-70
curl fingerprint Request from curl library +45-65
Python requests Common in scripts/bots +40-60
Headless Chrome TLS Differs from regular Chrome +35-55
Go HTTP client Often used in scanners +40-55
Node.js fetch Server-side requests +30-45
Mismatched TLS/UA TLS says Python, UA says Chrome +55-75

Why it matters: TLS fingerprints are hard to spoof because they’re generated at the protocol level before any application code runs. They reliably identify curl, wget, Python requests, and headless browsers even when User-Agent strings are spoofed.

JA3 Fingerprint Example:

TLS Handshake Analysis:
├── Cipher Suites: [specific order unique to client]
├── Extensions: [TLS extensions and order]
├── Curves: [supported elliptic curves]
└── Point Formats: [EC point formats]
JA3 Hash: 769,47-53-5-10-49161-49162-49171-49172...
Match: Python/requests 2.28.x
→ TLS Score: 58

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
Known malicious IP Threat intelligence feeds +60-80
Datacenter hosting IP belongs to cloud provider +20-35
TOR exit node IP is TOR network endpoint +40-55
High abuse reports Many reports on AbuseIPDB +35-50
Open proxy IP listed as open proxy +30-45
VPN service Known VPN provider IP +15-30
Residential proxy Suspicious residential IP +25-40

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 Accept header No content type preference +25-40
No Referer Direct access to deep pages +15-25
Unusual header order Non-browser header ordering +20-35
Missing cookies No cookie support +15-25
Missing Accept-Language No language preference +20-30
Missing Accept-Encoding No compression support +15-25

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
→ Header Score: 45

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 The registry’s base score for that agent
curl/wget UA “curl/7.68.0”, “Wget/1.20” +50-70
Empty User-Agent No UA provided +60-80
Scripting library UA “python-requests”, “axios” +40-60
Outdated browser Chrome 60 when current is 120 +20-35
Malformed UA Syntax errors or truncated +35-50
Chromium UA with no client hints Claims Chrome, sent no Sec-CH-UA +50

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.

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 Typical Score
Attacker ⚠️ Attack signatures (SQLi, XSS, etc.) Active exploitation attempts 70-100
Bot 🤖 Honeypot + fingerprint anomalies Automated traffic with technical non-human signs 60-90
Scanner 📡 Any honeypot/decoy trigger Reconnaissance or vulnerability scanning 40-80
Crawler 🕷️ Known crawler User-Agent Web crawlers and indexing bots 20-50
Scraper 📋 Fingerprint anomalies (no honeypot) Content scraping or data harvesting 35-65
Legitimate All signals below threshold Normal human visitor 0-25

Attacker:

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

Bot:

Accessed: /admin/backup.zip (honeypot)
Fingerprint: WebDriver=true, no plugins
Honeypot Score: 75, Fingerprint Score: 68
→ Category: BOT

Scanner:

Accessed: /.git/config (decoy)
Normal fingerprint otherwise
Honeypot Score: 45
→ 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 hundreds of addresses by design. Over 14 days the flat rotation bonus pushed roughly 2,400 detections from range-verified and rDNS-verified agents up into HIGH and CRITICAL: 1,565 verified ChatGPT-User requests for ordinary blog pages (honeypot score 0) sitting at CRITICAL 86, and 296 forward-confirmed Bingbot fetches between 77 and 94.

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.


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) {
const { score, confidence, category } = detection;
// Critical threats - block immediately
if (score >= 80 && confidence >= 60) {
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: Filter to category = attacker to investigate active exploitation attempts
  • Scanner review: Filter to category = scanner to see what reconnaissance activity is happening
  • Legitimate verification: Filter to category = legitimate with high scores to find potential false positives

Reducing False Positives:

  1. Increase block threshold (e.g., 75 → 85)
  2. Add known good IPs to allowlist
  3. Verify good bots (Googlebot, Bingbot) by IP
  4. Review medium-score detections manually

Catching More Threats:

  1. Lower block threshold (e.g., 75 → 65)
  2. Add more honeypot links to pages
  3. Enable Detection Script Pro for JavaScript 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.