Overview
Thehoneypot middleware monitors requests to commonly attacked paths (like /admin, /.env, /wp-admin) and blocks IPs that access them. It acts as a trap for attackers and bots scanning for vulnerabilities.
Use it when you need:
- Detect automated vulnerability scanners
- Block malicious IPs proactively
- Reduce attack surface
- Log attack attempts
Installation
Quick Start
Configuration
Options
| Option | Type | Default | Description |
|---|---|---|---|
Paths | []string | Common attack paths | Paths to monitor |
BlockDuration | time.Duration | 1h | How long to block detected IPs |
Response | func(*mizu.Ctx) error | 404 Not Found | Response for honeypot requests |
OnTrap | func(ip, path string) | - | Callback when trap triggered |
Default Paths
Examples
Default Configuration
Custom Paths
Admin Path Honeypot
Config File Honeypot
Database Path Honeypot
With Logging
Custom Block Duration
Custom Response
Form Field Honeypot
Detect bots that fill hidden form fields:Comprehensive Protection
Combined with IP Filter
API Reference
Functions
How It Works
- Request arrives at a honeypot path
- IP recorded in block list with expiration
- Callback triggered (if configured) for logging/alerting
- Fake response returned to attacker
- Future requests from that IP are blocked
Technical Details
Architecture
The honeypot middleware uses an in-memory block list with automatic cleanup to track and block malicious IPs:Request Flow
- IP Extraction - Client IP is extracted with proxy support (X-Forwarded-For, X-Real-IP)
- Block Check - If IP is in block list and not expired, return 403 Forbidden
- Path Matching - Current path is checked against honeypot path map (O(1) lookup)
- Trap Trigger - If path matches:
- IP is added to block list with expiration time
- OnTrap callback is invoked (if configured)
- Custom/default response is returned
- Pass Through - If no match, request continues to next handler
Implementation Details
- Concurrent Access - Block list uses sync.RWMutex for thread-safe operations
- Automatic Cleanup - Background goroutine runs every 10 minutes to remove expired entries
- Path Lookup - Paths stored in map[string]bool for O(1) lookup performance
- IP Detection Priority:
- X-Forwarded-For header
- X-Real-IP header
- Request.RemoteAddr
Memory Management
- Block list grows with unique trapped IPs
- Automatic cleanup prevents unbounded growth
- Each entry: IP string + time.Time (approximately 24-32 bytes)
- Recommended for moderate traffic; for high-traffic consider external storage
Form Honeypot Implementation
Form honeypots use a simpler stateless approach:- Check if hidden field contains any value
- No IP blocking or state management
- Returns 400 Bad Request immediately if filled
Security Considerations
- False Positives - Legitimate users might accidentally hit honeypot paths
- IP Rotation - Attackers may rotate IPs
- Proxy Detection - Consider X-Forwarded-For for accurate blocking
- Log Analysis - Monitor trapped IPs for patterns
Best Practices
- Choose honeypot paths that legitimate users won’t access
- Set appropriate block duration based on attack patterns
- Log all triggered traps for security analysis
- Combine with other security measures
- Don’t use paths that might be legitimately requested
Testing
The honeypot middleware includes comprehensive test coverage for all functionality:| Test Case | Description | Expected Behavior |
|---|---|---|
TestNew - normal path | Request to non-honeypot path | Returns 200 OK, request passes through |
TestNew - honeypot path | Request to default honeypot path (/admin) | Returns 404 Not Found, IP blocked |
TestWithOptions_CustomPaths - custom trap path | Request to custom honeypot path | Returns 404 Not Found for custom paths |
TestWithOptions_CustomPaths - default path not trapped | Request to default path when custom paths set | Passes through (default paths not active) |
TestWithOptions_OnTrap | Honeypot triggered with OnTrap callback | Callback invoked with IP and path |
TestWithOptions_CustomResponse | Honeypot with custom response function | Returns custom status (418 Teapot) and JSON |
TestBlockedIP - first request | Initial request to honeypot path | Returns 404, IP added to block list |
TestBlockedIP - subsequent request | Normal request from blocked IP | Returns 403 Forbidden |
TestPaths | Custom paths using Paths() function | Custom paths trigger honeypot |
TestAdminPaths | AdminPaths() preset paths | Admin-related paths trigger honeypot |
TestConfigPaths | ConfigPaths() preset paths | Config file paths (/.env) trigger honeypot |
TestDatabasePaths | DatabasePaths() preset paths | Database paths (/phpmyadmin) trigger honeypot |
TestForm - empty honeypot field | Form submission with empty hidden field | Returns 200 OK, request passes |
TestForm - filled honeypot field | Form submission with filled hidden field | Returns 400 Bad Request, blocks bot |