Skip to content

Endpoints (API Honeypots)

An endpoint decoy is a fake API endpoint that captures detailed information about attackers probing your APIs for vulnerabilities. Unlike simple decoy links, endpoints can restrict which HTTP methods they accept and can capture request bodies, which WebDecoy scans for attack patterns.

For use cases and product capabilities, see the Endpoint Decoys product overview.

Feature Decoy Link Endpoint Decoy
HTTP Methods Any Any, or only the methods you allow (GET, POST, PUT, DELETE, PATCH)
Body Capture No Optional (POST, PUT, DELETE, PATCH)
Attack Signatures None SQL injection, command injection, XSS, path traversal, mass assignment, XXE, serialized objects
Expected Content-Type N/A Recorded with the decoy
Use Case Crawlers, scanners API attacks, vulnerability probing
Attacker → POST /api/admin/users
{"username": "admin", "password": "' OR '1'='1"}
│
▼
Endpoint Decoy receives request
│
▼
Attack signature detected: sql_injection
│
▼
Detection created with request details
│
▼
MITRE tactic inferred from the decoy path: TA0043 (Reconnaissance)

  1. Navigate to Decoys

    • Click Decoys in the sidebar
  2. Click “Create Decoy”

    • The Create New Decoy dialog opens
  3. Select Decoy Type: API Endpoint

    • Switch the toggle from Honeypot Link to API Endpoint
  4. Configure the Endpoint

    Field Description Example
    Name Internal name “Admin API Honeypot”
    Path API endpoint path /api/v1/admin/users
    Action on Detection What the endpoint returns: Log, Block, Poison or Redirect Log
    Allowed HTTP Methods HTTP methods to accept (none selected = all) POST, PUT, DELETE
    Capture Request Bodies Store request bodies and scan them for attack patterns On
    Expected Content-Type Content type you expect the endpoint to receive application/json
    Hosting Use the WebDecoy shared domain (default) or a verified custom domain Shared domain
  5. Click “Create Decoy”

    • Your endpoint decoy is active immediately
Name: Admin API Honeypot
Domain: api.yoursite.com
Path: /api/v1/admin/users
Allowed HTTP Methods: GET, POST, PUT, DELETE
Capture Request Bodies: On
Expected Content-Type: application/json
Action on Detection: Log

This creates a fake admin API that captures any requests to:

  • GET /api/v1/admin/users - List users attempt
  • POST /api/v1/admin/users - Create user attempt
  • PUT /api/v1/admin/users - Update user attempt
  • DELETE /api/v1/admin/users - Delete user attempt

Select which HTTP methods your endpoint should accept:

Method Typical Attack Detection Value
GET Information disclosure Low - common crawling
POST Data injection, authentication bypass High - active attack
PUT File upload, data modification High - active attack
DELETE Data destruction attempts High - active attack
PATCH Partial data modification Medium - targeted attack

A request with a method you did not allow receives 405 with {"error": "method not allowed"} and does not create a detection. If you select no methods, every method is accepted.

Recommendation: Enable POST, PUT, and DELETE for API honeypots to catch actual attack attempts.

When enabled, WebDecoy reads the body of POST, PUT, DELETE and PATCH requests (up to 1 MB), scans it for attack signatures, and stores it in the detection. GET and HEAD requests are never read. Attack signature detection only runs on captured bodies, so leave this on for API honeypots.

The detection records:

Field Description
metadata.request_body The raw body as a string, truncated to 10 KB
metadata.attack_signatures Attack signatures found in the body
request_body_size Body size in bytes
content_type The request’s Content-Type header
request_method The HTTP method
has_auth_header Whether an Authorization header was present

Privacy Note: Body capture may contain sensitive data. Review your data retention policies.

Record what content type the endpoint expects:

Content-Type Use Case
Any No expectation (default)
application/json REST API honeypot
text/xml XML/SOAP API honeypot
application/x-www-form-urlencoded Form submission honeypot
multipart/form-data File upload honeypot

The expected content type is stored with the decoy; requests with a different Content-Type are still accepted and recorded. Signature checks that depend on the format use the request’s own Content-Type header: mass assignment is checked only for application/json bodies, and XXE only for XML bodies.

The action decides what the endpoint returns after the detection is recorded:

Action Response
Log (default) 200 with {"status": "ok"}
Block 403 with {"error": "access forbidden"}
Poison 200 with the Poison Content (JSON) you provide. Without it: {"status": "success", "data": [], "message": "Request processed", "timestamp": ...}
Redirect 302 to the Redirect URL you provide. Without one it falls back to 200 with {"status": "ok"}

Status codes, response headers and response bodies other than the Poison content cannot be customized.

Example Poison Content (Fake API):

{
"status": "success",
"message": "User created",
"user_id": "fake-uuid-12345"
}

Endpoint decoys with Capture Request Bodies on scan each captured body for common attack patterns.

Signature Example patterns Condition
sql_injection ' OR '1'='1, UNION SELECT, ; DROP , WAITFOR DELAY, SLEEP(5), xp_cmdshell Any body
command_injection ; whoami , | cat , `id`, $(uname, /bin/bash, bash -c, ${...}, eval( Any body
xss <script, <img ... onerror, <svg ... onload, <iframe, javascript:, onload= Any body
path_traversal ../, ..\, %2e%2e%2f, /etc/passwd, c:\windows Any body
mass_assignment "role": "admin", "isAdmin": true, "is_admin": true, "permissions": [ application/json bodies
xxe <!DOCTYPE with <!ENTITY, or SYSTEM with file: / http: XML bodies
php_serialization O: together with :{ Any body
java_serialization Body starts with rO0AB Any body

Query strings and headers are not scanned.

When an attack is detected, the detection includes the matched signatures and a raised score. Illustrative example (real field names):

{
"source": "endpoint",
"request_method": "POST",
"unified_score": 70,
"threat_category": "attacker",
"metadata": {
"path": "/api/v1/admin/users",
"request_method": "POST",
"request_body": "{\"username\": \"admin\", \"password\": \"' OR '1'='1\"}",
"attack_signatures": ["sql_injection"]
},
"mitre": {
"tactic": { "id": "TA0043", "name": "Reconnaissance" },
"confidence": "high"
}
}

Any detected signature sets threat_category to attacker. The MITRE tactic comes from the decoy’s path (an /admin/ path maps to Reconnaissance, a login path to Credential Access, a debug path to Discovery), not from the attack signature. The mitre object in the API response also lists candidate techniques for that tactic.

Each signature adds points to the detection’s Attack Signatures score component (shown as attack_signature_score in score_components):

Signature Component points
SQL Injection 50
Command Injection 60
XSS 40
Path Traversal 50
Mass Assignment 45
XXE 55
PHP / Java serialization 60

Each additional signature type adds a further 20 points, and the component is capped at 100. The component is one weighted input to the 0-100 unified threat score, alongside the honeypot signal that every decoy hit carries. See Threat Scoring.


These paths are commonly targeted by API attackers:

Category Example Paths
Authentication /api/auth/login, /api/token, /oauth/token
Admin /api/admin/*, /api/v1/admin/*, /admin/api/*
User Management /api/users, /api/users/admin, /api/users/delete
GraphQL /graphql, /api/graphql, /v1/graphql
Debug /api/debug, /api/health/debug, /api/config
File Operations /api/upload, /api/files, /api/download
Database /api/query, /api/sql, /api/export

Create decoys that mirror your real API structure:

Real API: /api/v1/users
Decoy: /api/v1/admin/users ← Looks like admin version
Decoy: /api/v2/users ← Looks like new version
Decoy: /api/users/export ← Looks like data export

Create endpoints attackers commonly probe:

/api/graphql ← GraphQL introspection attacks
/api/debug ← Debug information leakage
/api/config ← Configuration exposure
/api/admin/sql ← Direct database access
/.well-known/admin ← Admin discovery

If you have API documentation, add undocumented “internal” endpoints:

Documented: /api/v1/products (real)
Documented: /api/v1/orders (real)
Undocumented: /api/v1/internal/audit (decoy)
Undocumented: /api/v1/admin/impersonate (decoy)

With the Poison action, make the content you serve look realistic:

Bad (obvious fake):

{"error": "honeypot"}

Good (realistic API response):

{
"status": "error",
"code": "AUTH_REQUIRED",
"message": "Authentication required for this endpoint"
}

Even Better (enticing response):

{
"status": "success",
"data": {
"users": [
{"id": 1, "email": "[email protected]", "role": "admin"},
{"id": 2, "email": "[email protected]", "role": "user"}
]
},
"total": 2,
"page": 1
}

  1. Go to Detections in the sidebar
  2. Filter by Source: Endpoint
  3. Open a detection to see endpoint-specific details:
    • Request method (POST, PUT, DELETE)
    • Content-Type and whether an auth header was present
    • Detected attack patterns
    • Captured request body

The Decoys list shows each decoy’s action and detection count.

Set up alerts for endpoint detections:

  1. Go to Integrations and open Webhooks or Slack
  2. Filter what is sent:
    • A minimum score, so only high-scoring requests are sent
    • Specific decoys, so only your endpoint decoys trigger it

Create a suite of endpoint decoys:

Endpoint Path Methods Purpose
Auth Honeypot /api/auth/admin POST Catch credential stuffing
User Export /api/users/export GET Catch data exfiltration
Bulk Delete /api/orders/bulk-delete DELETE Catch destructive attacks
GraphQL Admin /graphql/admin POST Catch GraphQL attacks
SQL Query /api/internal/query POST Catch SQL injection
  1. Create each endpoint in WebDecoy
  2. Use the Poison action with realistic JSON where you want to keep the attacker engaged
  3. Monitor for:
    • Authentication bypass attempts
    • SQL injection in query endpoint
    • GraphQL introspection
    • Bulk data operations

Add client-side bot detection: