ESC
> PressHaven alpha

PressHaven Knowledge Hub

A defensive security platform built around a WordPress + WooCommerce shop as its target demo application — today a high-interaction honeypot, growing into a security management layer above WordPress + WooCommerce instances. It scores every request in real time and quietly diverts suspicious sessions into isolated honeypot clones. Real customers never notice; adversaries get a convincing storefront while every move is recorded.

Defensive only. The entire system observes, diverts and records on its own infrastructure. It deliberately performs no offensive tracking and no offensive security — no beacons or hack-back, no reaching out to adversary machines, no retaliation. Deception is used solely to protect the real store, never to strike back.

WordPress + WooCommerce Defensive only No tarpit Session-bound GDPR aware Pure / adapter split

Overview

Overview

Operations landing page: current risk score, both stacks' health, and a live feed of notable security events.

Risk score

Live

Stacks

2 tracked

Events

Live feed

● 22 pages 5 groups · click a page to explore
System at a glance last revision · v2.0
13
Seeded CVEs
70+
Suricata SIDs
12
Routing Stages
17
Pure Lua Modules
23
Unit Test Files
6
Kibana Dashboards
The idea

A real storefront that quietly becomes a trap.

The target demo application is a full WordPress + WooCommerce storefront — a coffee eshop with real products and carts — and both honeypot layers are built for and around it. In front of it sits an OpenResty reverse proxy that scores every non-static request in Lua: URI and header patterns, seeded WordPress and WooCommerce CVE signatures, request rate, session history, network IDS alerts and IP reputation.

Legitimate traffic continues to production. Once a session crosses the threshold it is bound to its own honeypot pool — a complete clone of the WooCommerce shop — and stays there. Carts follow the session, so the diversion is invisible and nothing about normal browsing changes.

  • Session-bound, not IP-bound. A signed cookie plus passive fingerprint recovery keeps the experience stable.
  • Elastic pools. One isolated shop and database per session, cloned from a pre-built template and recycled when idle.
  • Full telemetry. Security events and Suricata alerts flow through Vector into Elasticsearch and Kibana.
REQUEST LIFECYCLE EDGE HOST CLIENT HTTP OPENRESTY analyze_request() decide_route() 12 stages PRODUCTION SHOP legitimate traffic HONEYPOT POOL N isolated shop + database SURICATA eve.json REDIS session + pools VECTOR → ELASTICSEARCH → KIBANA
Scoring and diversion stay in the request path no tarpit
Architecture

One decision pipeline, two deployment shapes.

All detection logic lives in pure *_rules.lua modules with zero ngx.* dependencies. Thin adapters perform I/O, which keeps the rules unit-testable under a plain Lua interpreter and the edge behaviour deterministic.

Request pipeline

Client Request → Nginx access_by_lua_block
  → pattern_analyzer.analyze_request()
  → router.decide_route() (12 stages)
  → pool_router.get_or_assign_pool()
  → session_handler.update_session() → Redis
  → WordPress backend: production or honeypot
  → Suricata eve.json → init_worker.lua
  → threat_intel shared dict
  → abuseipdb_client.report_ip_async()
  • Pure / adapter split. Decisions live in rules modules; adapters talk to Redis, Nginx and AbuseIPDB.
  • Graceful degradation. If Redis or a pool is unavailable, the router falls back instead of dropping customer traffic.
  • Two hosts, one flow. The edge can ship telemetry to a separate SIEM host over mTLS, outbound only.
TWO-HOST TOPOLOGY mTLS · OUTBOUND EDGE HOST REVERSE PROXY OpenResty + Lua PRODUCTION SHOP WordPress + Woo HONEYPOT POOLS shop + database N REDIS sessions · routes SURICATA eve.json alerts VECTOR SHIPPER security events SIEM HOST VECTOR aggregator ELASTICSEARCH index + retention KIBANA 6 dashboards
Edge detection · SIEM storage both can share one host
Edge host

Reverse proxy and Lua scoring, production WordPress, elastic honeypot pools, Redis session state, Suricata, and a local Vector shipper. This is the only host that sees plaintext client requests.

SIEM host

Vector aggregator, Elasticsearch and Kibana. Logs arrive over an outbound-only mTLS channel, so the SIEM never needs to initiate a connection into the edge network.

SIGNAL FUSION 0 → 100 URI · HEADERS pattern_rules.lua CVE SIGNATURES vulnerability_rules.lua SURICATA ALERTS suricata_rules.lua SESSION HISTORY router_rules.lua IP REPUTATION threat_intel dict RISK SCORE 0 – 100 accumulated + decayed explainable per signal ROUTE DECISION threshold 80 · 12 stages CVE / plugin / reputation PRODUCTION HONEYPOT POOL sticky for the session DECAY · half-life 300 s · permaflag after 5 offenses EVERY SCORE IS AUDITABLE
Rules produce signals; signals produce a decision explainable by design
Detection

Layered signals, one readable score.

Detection is not a single regex. Each request passes through headers, URI patterns, seeded CVE signatures, rate and reputation checks, automation detection and session history. A signal can add a fixed score, contribute a severity-derived delta, or trigger a hard routing rule.

01 Pattern and header analysisFlagged user agents, missing headers, traversal, injection and upload indicators. +5 … +80
02 Seeded CVE matchingWordPress plugin exploits matched against URI, arguments and specific headers. +40 / CVE
03 Network IDS correlationSuricata alerts parsed from eve.json and converted to severity-graded deltas. +10 … +50
04 Escalation-aware decayRepeat offenders decay more slowly; permaflag stops decay entirely. half-life

Read the detection overview

Operations

Pools that scale with people, not noise.

Assignment is per session and atomic in Redis. A spare pool is kept ready, another is provisioned as soon as a session has to borrow one, and idle pools are recycled after thirty minutes. Resource budgets stop growth before the host runs short.

  • Exclusive by default. A session gets its own shop and database pair; the mapping is stored with a 24-hour TTL.
  • Spare provisioning. Every assignment queues a wake-up, so the next visitor usually finds a warm pool.
  • Bounded growth. POOL_MAX, memory, CPU, load and disk guards cap the fleet; beyond that sessions share pools round-robin.
  • Scale down. Idle pools above the spare count are removed and their users reassigned on return.
  • Content sync. Production pages, posts and products are mirrored into every pool every five minutes by default.

Explore the honeypot engine

POOL LIFECYCLE POOL_MAX · 10 SESSION signed cookie POOL ROUTER atomic Redis EVAL READY POOL shop + database pair sticky binding BOUND SESSION same pool on every request borrow if none free POOL FLEET POOL 01 spare POOL 02 assigned POOL 03 building POOL 04 idle POOL 05 ready scaledown after 30 min idle · content sync every 5 min
Assignment, spare provisioning, reuse, scale-down isolated per session
Honest assessment

What works, and what still does not.

The project documents its own limits. These are the trade-offs recorded in the manuals, not marketing footnotes.

Strengths
  • Multi-layered detection with WSTG mappings
  • Explainable, auditable risk scoring
  • Per-adversary isolation via elastic pools
  • No tarpit — identical proxy latency
  • Privacy-preserving GDPR identity
  • Honeytoken injection for high-confidence signals
  • Pure / adapter split with 23 unit test files
  • Severity-graded Suricata integration
Limitations
  • Same-host Suricata testing gap
  • Decay system has four tuning parameters
  • Honeytoken coverage is limited to five types
  • Rule-based only — no machine learning
  • Redis is a single point of failure
  • Pool scaling is bounded by host resources
  • No end-to-end integration test suite
  • Dashboard state can drift from live Kibana

Read known issues and workarounds

Start here

Go from zero to a diverted attack.

Follow the setup path, then read the module that made the decision. Every page links back to the exact Lua file or deployment script it describes.

12-stage routing 13 seeded CVEs 6 dashboards 23 test suites