FCaptcha v1.45: Works With Gitea, No Code
FCaptcha v1.45 serves its widget on the Turnstile, hCaptcha and reCAPTCHA script paths, so apps that let you change those URLs can use it with config alone.
integrationForward WebDecoy bot detections to Splunk HEC, CrowdStrike Falcon LogScale, Datadog Logs, or a signed webhook. Real event fields, setup steps, and searches.
SIEM bot detection starts by sending labeled automation events, not raw access logs, into the tools your analysts already use. Without that label, credential stuffing, scraping, and automated probing look like ordinary authentication failures and HTTP requests.
That credential stuffing run hitting your login page at 3 AM? It looks like normal authentication failures. That scraper pulling your pricing pages? Just another HTTP 200. That vulnerability scanner probing your API paths? Lost in the noise of legitimate traffic.
WebDecoy forwards each detection it records to Splunk (HTTP Event Collector), CrowdStrike Falcon LogScale, Datadog Logs, or any HTTPS endpoint through a signed webhook. This guide covers what those events actually contain, how to set each one up, and searches written against the real field names.
Traditional SIEMs are built to correlate known threats: malware signatures, CVE exploits, suspicious login patterns. They excel at connecting dots when the dots are labeled.
Bot attacks create unlabeled dots.
A careful scraper does not trigger your IDS. It does not match a malware hash. It generates legitimate-looking HTTP requests that your WAF waves through.
Consider what your SIEM sees during a typical bot attack:
2025-11-27T03:14:22Z web-01 nginx: 192.168.1.100 - - "POST /api/login HTTP/1.1" 401 0.023s
2025-11-27T03:14:22Z web-01 nginx: 192.168.1.101 - - "POST /api/login HTTP/1.1" 401 0.019s
2025-11-27T03:14:23Z web-01 nginx: 192.168.1.102 - - "POST /api/login HTTP/1.1" 401 0.021sThree failed logins from three IPs. Could be a botnet cycling through a credential list. Could be three users who forgot their passwords. The access log cannot tell the difference.
A WebDecoy detection adds the missing label: this IP touched a decoy, tripped a sensor, or scored as automation, with a score, a threat level, and a category. Once that event sits next to your auth logs, you can join on the IP address.
WebDecoy has four ways to get detections out:
| Destination | Transport | What it carries |
|---|---|---|
| Splunk | HTTP Event Collector (/services/collector/event) | The richest SIEM event: scores, threat level and category, network flags, GeoIP, reverse DNS |
| CrowdStrike Falcon LogScale | LogScale HEC endpoint (/api/v1/ingest/hec) | Scores, threat level and category, signature checks, plus the detection’s raw fingerprint and metadata objects |
| Datadog | Datadog HTTP logs intake | A compact log: IP, user agent, bot_score, event type, enforcement status |
| Webhooks | HTTPS POST, HMAC-signed | A compact payload you can route anywhere, including SIEMs WebDecoy has no dedicated integration for |
A few things to know before you design around them:
detection_id: GET /organizations/{org}/detections/{id}.Splunk, CrowdStrike, and Datadog integrations each have trigger toggles (On Detection, On High Risk, On Rule Enforced) and optional filters (a minimum score, and a list of specific decoys). Splunk and Datadog label each event with an event_type:
event_type | Meaning |
|---|---|
detection | A new detection was recorded |
high_risk_detection | unified_score (or, if absent, bot_score) is 80 or higher |
rule_enforced | A response action enforced against the detection |
test | Sent by the integration’s Test button |
CrowdStrike’s high-risk trigger uses the threat level instead: it fires on HIGH or CRITICAL.
Go to Integrations → Splunk and click Add Splunk Integration. The fields are:
| Field | Notes |
|---|---|
| HEC URL | Base URL, for example https://<your-server>:8088 or https://http-inputs-<stack>.splunkcloud.com:443. WebDecoy appends /services/collector/event itself |
| HEC Token | Stored encrypted, never shown again |
| Index | Optional; leave blank to use the token’s default |
| Source | Defaults to webdecoy |
| Source type | Defaults to webdecoy:detection |
| Verify SSL | On by default; turn off only for an on-prem HEC with a self-signed certificate |
| Triggers and filters | On Detection / On High Risk / On Rule Enforced, minimum score, specific decoys |
Click Test to send a test event, then check that it arrived:
index=<your index> source=webdecoy event_type=testEach detection is posted as one HEC event. Fields that have no value for a given detection are left out rather than sent as null.
Illustrative example:
{
"time": 1732691662.123,
"host": "webdecoy",
"source": "webdecoy",
"sourcetype": "webdecoy:detection",
"index": "security",
"event": {
"detection_id": "8f0c2d4e-...",
"event_type": "high_risk_detection",
"rules_enforced": false,
"timestamp": "2025-11-27T03:14:22Z",
"organization_id": "…",
"property_id": "…",
"decoy_id": "…",
"ip_address": "203.0.113.45",
"user_agent": "python-requests/2.31.0",
"source_type": "decoy_link",
"unified_score": 87,
"bot_score": 92,
"threat_level": "HIGH",
"threat_category": "scanner",
"confidence": 0.9,
"request_method": "GET",
"is_proxy": true,
"geo_country": "…",
"geo_city": "…",
"abuse_confidence_score": 97,
"reverse_dns_hostname": "…"
}
}The full set of event fields:
| Field | Description |
|---|---|
detection_id, event_type, rules_enforced, timestamp | Always present |
organization_id, property_id, decoy_id, scanner_id | Resource identifiers |
ip_address, user_agent, referer, request_method | Request details |
source_type | Which sensor produced it, such as decoy_link, bot_scanner, endpoint, sdk |
unified_score | Headline score, 0 to 100 |
bot_score | Bot-likelihood component |
threat_level | MINIMAL, LOW, MEDIUM, HIGH, CRITICAL |
threat_category | For example scraper, scanner, attacker, crawler |
confidence | Confidence in the score, 0 to 1 |
is_vpn, is_proxy, is_tor, is_relay | Present (as true) only when the flag is set |
signature_verified, token_verified, cryptographic_trust | Cryptographic identity checks (see verifying signed bots) |
geo_country, geo_city, geo_latitude, geo_longitude | From GeoIP enrichment, when available |
abuse_confidence_score | AbuseIPDB score, when enrichment ran |
reverse_dns_hostname, is_known_bot, known_bot_name | Reverse DNS results |
rule_enforcement_error | Set when a response action tried to enforce and failed |
There is no JA3/JA4 fingerprint, MITRE mapping, or request path in the Splunk event. Those live on the detection itself, available through the API.
Splunk extracts JSON fields automatically for the _json sourcetype. If you keep the default webdecoy:detection sourcetype, either set KV_MODE = json for it in props.conf or add | spath to your searches. The searches below assume the fields are extracted.
Detections by threat level
index=security source=webdecoy
| stats count by threat_levelHigh-risk detections, highest score first
index=security source=webdecoy threat_level IN ("high", "critical")
| table _time, ip_address, source_type, threat_category, unified_score, user_agent
| sort - unified_scoreTop sources by volume and score
index=security source=webdecoy
| stats count, max(unified_score) as max_score, values(threat_category) as categories by ip_address
| sort - count
| head 20Detections from anonymizing networks
index=security source=webdecoy (is_vpn=true OR is_proxy=true OR is_tor=true)
| stats count by ip_address, geo_countryDetection volume by sensor
index=security source=webdecoy
| timechart span=1h count by source_typeThis is where the SIEM earns its keep. Join WebDecoy’s labeled IPs against successful logins from the same addresses. Adjust the auth index and field names to your own data:
index=auth action=success
[ search index=security source=webdecoy threat_level IN ("high", "critical") earliest=-2h
| stats count by ip_address
| rename ip_address as src_ip
| fields src_ip ]
| table _time, src_ip, user, appIf a source that tripped a decoy also logged in successfully, that account deserves a look.
https://cloud.us.humio.com, or your regional URL)Go to Integrations → CrowdStrike and click Add CrowdStrike Integration:
| Field | Notes |
|---|---|
| Name | Friendly name |
| LogScale URL | Your instance base URL; WebDecoy posts to /api/v1/ingest/hec on it |
| Ingest Token | Stored encrypted |
| Source / Source Type | Default webdecoy / webdecoy:detection |
| Triggers | On Detection, On High Risk (threat level HIGH or CRITICAL, the default), On Rule Enforced |
| Filters | Minimum score, specific decoys |
LogScale receives an HEC-format event with these fields in event: detection_id, timestamp, detection_type (the sensor source, such as decoy_link), threat_level, source_ip, user_agent, referer, unified_score, confidence, threat_category, cryptographic_trust, signature_verified, signature_agent, property_id, organization_id, decoy_id, rule_enforced, request_method, and the detection’s raw fingerprint and metadata objects when present. The event also carries #severity, #product (webdecoy), and #detection_source fields.
Note that the IP field is source_ip here, not ip_address as in Splunk and Datadog.
Depending on your parser, fields may appear at the top level or under an event. prefix. Check one event first and adjust. With top-level fields:
High and critical detections
sourcetype="webdecoy:detection"
| threat_level=/^(high|critical)$/i
| sort(@timestamp, order=desc)Top sources
sourcetype="webdecoy:detection"
| groupBy(source_ip, function=[count(), avg(unified_score)])
| sort(_count, order=desc)
| head(20)Detections by sensor
sourcetype="webdecoy:detection"
| groupBy(detection_type, function=count())From there, the LogScale repository is yours: correlate source_ip with your other Falcon data, build dashboards, or alert on it with your own LogScale alerts. WebDecoy does not trigger Falcon Fusion workflows or modify your IOC lists.
The Datadog integration is a log integration, not a metrics one. Each detection becomes one log entry in the Datadog HTTP logs intake.
datadoghq.com, us3.datadoghq.com, us5.datadoghq.com, datadoghq.eu, or ap1.datadoghq.com), the Service Name and Source (both default to webdecoy), and any extra Tagsservice:webdecoy in Live TailIllustrative example:
{
"message": "High risk detection: bot_score=92.0 ip=203.0.113.45",
"ddsource": "webdecoy",
"ddtags": "env:production,event_type:high_risk_detection,team:security",
"hostname": "webdecoy",
"service": "webdecoy",
"status": "error",
"@timestamp": "2025-11-27T03:14:22Z",
"attributes": {
"detection_id": "8f0c2d4e-...",
"event_type": "high_risk_detection",
"rules_enforced": false,
"timestamp": "2025-11-27T03:14:22Z",
"decoy_id": "…",
"organization_id": "…",
"property_id": "…",
"ip_address": "203.0.113.45",
"user_agent": "python-requests/2.31.0",
"bot_score": 92
}
}status is error for high-risk detections, warning for rule enforcement, and info otherwise. The Datadog log does not carry unified_score, threat level, or GeoIP; fetch the detection by detection_id when you need them.
logs("service:webdecoy @attributes.bot_score:>=80").index("*").rollup("count").last("5m") > 0logs("service:webdecoy @attributes.event_type:detection").index("*").rollup("count").last("15m") > 100For a SIEM without a dedicated integration, use a webhook. Go to Integrations → Webhooks → Add Webhook, give it an HTTPS URL, and pick triggers. Every request is a POST with these headers: X-WebDecoy-Signature (HMAC-SHA256 of the raw body, as sha256=<hex>), X-WebDecoy-Event, X-WebDecoy-Delivery (a unique delivery ID), and User-Agent: WebDecoy-Webhook/1.0.
The payload, from the webhook docs:
{
"event": "detection",
"timestamp": "2026-07-15T10:30:00Z",
"detection": {
"id": "det_abc123",
"decoy_id": "decoy_uuid",
"organization_id": "org_xyz789",
"ip_address": "192.168.1.100",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...",
"bot_score": 92,
"timestamp": "2026-07-15T10:30:00Z",
"rules_enforced": true,
"source": "decoy_link"
},
"metadata": {}
}Each event is delivered once, with no automatic retries, and your endpoint has 10 seconds to respond. For a SIEM pipeline that means: verify the signature, return 200 immediately, queue the event, and index it from a worker. If you want the richer fields, have the worker fetch the full detection from the API by detection.id before indexing.
That receiver is the whole Elastic story today: WebDecoy has no native Elasticsearch output, Kibana dashboards, or Elastic detection rules.
The setup pages in the docs have the full field lists: Splunk, CrowdStrike, Datadog, and webhooks.
Review the supported WebDecoy integrations, then start free and send a test event to your SIEM.
Questions about an integration? Contact us.
FCaptcha v1.45 serves its widget on the Turnstile, hCaptcha and reCAPTCHA script paths, so apps that let you change those URLs can use it with config alone.
integrationWebDecoy is live on Shopify. Detect bot traffic, investigate risky orders, track AI crawlers and referrals, and choose your response with Shopify Flow.
integrationWebDecoy now reads your Fastly logs to find crawlers that never run JavaScript, and blocks addresses in a Fastly ACL. No application code.
integrationLike this post? Share it with your friends!
Get a personalized demo from our team.