Wordpot: Building a WordPress Honeypot That Never Runs WordPress
Hook
The best WordPress security tool might be one that never actually runs WordPress at all—just convincingly pretends to.
Context
In the early 2010s, WordPress powered roughly 20% of the web, making it an irresistible target for automated attack tools. Botnets would carpet-bomb IP ranges looking for vulnerable WordPress installations, probing for outdated plugins like TimThumb, weak admin credentials, and unpatched themes. Security teams faced a dilemma: they wanted to understand these attack patterns without exposing real WordPress installations to compromise.
Traditional honeypots were either too generic (capturing all HTTP traffic without WordPress-specific context) or too dangerous (running actual vulnerable WordPress instances that could be weaponized if attackers pivoted). Wordpot emerged as a middle path: a lightweight Python application that speaks enough WordPress to fool reconnaissance tools, logging attack attempts while presenting zero actual attack surface. It's deception infrastructure purpose-built for the most targeted CMS on the internet.
Technical Insight
Wordpot's architecture is deceptively simple: a Python web server that returns WordPress-flavored responses without touching PHP or MySQL. The core trick is mimicking WordPress's filesystem fingerprints—the predictable paths, directory listings, and file structures that automated scanners rely on to identify targets.
The honeypot uses Jinja2 templates to render authentic-looking WordPress pages. Here's how it handles a common reconnaissance probe for the wp-login.php endpoint:
@app.route('/wp-login.php', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('log', '')
password = request.form.get('pwd', '')
# Log the credential attempt
logger.warning('Login attempt: user=%s pass=%s from %s' %
(username, password, request.remote_addr))
# Always return authentication failure
return render_template('wp-login.html',
error='Invalid username or password')
return render_template('wp-login.html')
This code captures credential stuffing attempts and brute force attacks while never validating against a real user database. The honeypot always fails authentication, but does so with timing and responses that match genuine WordPress behavior.
Wordpot's plugin system extends this pattern to common vulnerability targets. The TimThumb vulnerability—a critical remote code execution flaw that plagued WordPress sites in 2011-2012—can be emulated without actually running exploitable code:
@app.route('/wp-content/themes/<theme>/timthumb.php')
@app.route('/wp-content/plugins/<plugin>/timthumb.php')
def timthumb(theme=None, plugin=None):
# Log the probe attempt with full query parameters
logger.critical('TimThumb probe detected: %s from %s' %
(request.url, request.remote_addr))
# Return a response that suggests vulnerability without executing anything
return 'TimThumb version 1.33', 200
Attackers scanning for TimThumb receive just enough information to believe they've found a vulnerable installation, but any exploitation attempt hits a dead end. The honeypot logs the attack pattern—which parameters were tested, what payloads were attempted—without ever parsing image files or making external HTTP requests.
The configuration system uses YAML to define which WordPress version to advertise, which plugins and themes to expose, and what server headers to return. This allows researchers to test different attack profiles:
wordpress:
version: '3.5.1'
plugins:
- name: 'akismet'
version: '2.5.6'
- name: 'contact-form-7'
version: '3.3.2'
themes:
active: 'twentytwelve'
available:
- 'twentyeleven'
- 'twentyten'
By rotating these configurations, you can measure whether attackers preferentially target specific WordPress versions or whether certain plugins attract more attention. The honeypot becomes a sensor for measuring attack trends rather than just a binary tripwire.
Wordpot's logging captures not just what was attacked, but the attack methodology. Examining log patterns reveals whether attackers are using manual tools, automated scanners like WPScan, or custom botnet code. The User-Agent strings, request timing, and probe sequences all leak information about attacker infrastructure.
Gotcha
Wordpot's most significant limitation is its age. The codebase targets WordPress 3.x-era reconnaissance patterns, but modern WordPress has evolved considerably. Current versions use different admin interfaces, REST API endpoints, and plugin architectures that sophisticated attackers will recognize as missing. A determined attacker running updated fingerprinting tools will quickly identify Wordpot as a honeypot rather than a genuine installation.
The plugin system, while conceptually elegant, is marked as beta and lacks documentation. Adding custom vulnerability emulations requires reading the source code to understand the expected hook patterns. There's no plugin marketplace or community-contributed modules, so you're building extensions from scratch. Additionally, Wordpot provides no integration with modern threat intelligence platforms, SIEM systems, or incident response workflows—it writes to local log files and nothing more. For production security operations, you'd need to build substantial tooling around it to extract value from the captured data.
Verdict
Use if: You're researching WordPress-specific attack patterns and need a lightweight, resource-efficient way to attract and log reconnaissance attempts without running actual WordPress infrastructure. It's also valuable if you're learning honeypot architecture and want to study a focused, readable codebase that demonstrates deception principles. Skip if: You need a maintained, production-ready honeypot that understands modern WordPress (5.x+) with its REST API, block editor, and contemporary plugin ecosystem. Also skip if you require integration with existing security operations tools or want a turnkey solution—Wordpot is a research artifact that demands significant customization and modernization to be operationally useful in 2024.