honeypot-tarpits — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited honeypot-tarpits (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A honeypot is a resource that exists only to be hit by attackers. Anyone who interacts with it is, by definition, doing something they should not be. That makes honeypots one of the highest-signal detection mechanisms available — almost zero false positives, and trivial to operate at small scale.
This skill covers practical, low-effort patterns for solo operators and small teams. Not enterprise deception platforms (Thinkst Canary, etc., are excellent if you can afford them — but the same ideas work DIY).
Common scanner targets — /wp-admin/, /administrator/, /manager/, /phpmyadmin/, /.git/config — are reliable signals of automated probing. If you serve a real-looking 200 response and capture the source, you have an attacker IP/UA before they reach anything real.
# nginx — fake admin endpoint
location ~ ^/(wp-admin|administrator|phpmyadmin|manager/html|.git/config|.env)$ {
access_log /var/log/nginx/honeypot.log honeypot_fmt;
add_header Content-Type text/plain;
return 200 "OK"; # Looks fake, but the goal is the log entry, not realism
}
# Optional: in a separate http block, structured logging
log_format honeypot_fmt escape=json '{'
'"time":"$time_iso8601",'
'"ip":"$remote_addr",'
'"path":"$request_uri",'
'"method":"$request_method",'
'"ua":"$http_user_agent",'
'"referer":"$http_referer"'
'}';Pipe /var/log/nginx/honeypot.log to your alerting (Loki + Grafana alert, Better Stack, a tiny daemon that pings a webhook). Every hit is an attacker.
Optional escalation: feed honeypot-hit IPs straight to fail2ban or Cloudflare WAF block.
# /etc/fail2ban/filter.d/honeypot.conf
[Definition]
failregex = ^.*"ip":"<HOST>".*$
ignoreregex =# /etc/fail2ban/jail.local
[honeypot]
enabled = true
filter = honeypot
logpath = /var/log/nginx/honeypot.log
maxretry = 1
bantime = 24hOne hit = one day ban. Aggressive, but justified — nobody legitimately fetches /.env.
False-positive risk: search-engine bots occasionally hit weird paths from leaked logs. Whitelist verified Googlebot / Bingbot via reverse-DNS before banning.
.env and config filesSame idea, slightly more elaborate. A fake .env with realistic-shaped fake values lets you detect not just that someone scanned, but also if they tried to use what they found.
# /var/www/decoy/.env — serve at path /
# IMPORTANT: when you build your own decoy, generate the canary values
# from canarytokens.org so each token fires its own alert. Do NOT copy
# the placeholders below verbatim — they exist here purely for shape.
DB_HOST=127.0.0.1
DB_PORT=5432
DB_USER=app_user
DB_PASS=<canary-placeholder-replace-with-real-canary>
AWS_ACCESS_KEY_ID=<aws-canary-placeholder>
AWS_SECRET_ACCESS_KEY=<aws-canary-secret-placeholder>
STRIPE_SECRET_KEY=<stripe-canary-placeholder>Two layers of detection:
app_user user in your dev/staging DB with read-only access to a single decoy table; alert on any login attempt/login-shaped probes against your real Stripe endpoint patternsA canary token is a credential that exists only to fire an alert when used. canarytokens.org generates them for free; alternatives include Thinkst's commercial Canary platform.
Token types worth deploying:
.envPlace them where attackers will find them but legitimate users won't:
developer.txt file in /static/ with "internal credentials, do not commit"The placement matters more than the token. If no attacker ever finds your canary, it doesn't fire.
Frontend bundles get scraped automatically by tools looking for secrets that shouldn't be there. Plant fake keys with distinctive prefixes that you can grep on the wider web later.
// In your build, intentionally embed:
window.__INTERNAL_API_KEY__ = "intk_CANARY_a4e0e74e6d8c4f9aab3e1c7d8e2f5a1b";Then periodically search GitHub / pastebins / Discord for the string. If it shows up anywhere, you know your bundle was scraped and someone tried to use the value.
This is also useful as a tripwire on attacker-side automation that publishes "leaks" — your fake key in a paste means you caught a scanner.
Tarpits respond to scanners with deliberate latency, holding their connections open and reducing the volume they can probe per minute. Useful where blocking outright would be too aggressive.
# Slow response for known-bad UAs / paths
location ~ ^/(wp-admin|phpmyadmin|.env)$ {
if ($http_user_agent ~* "(masscan|nikto|sqlmap|nmap|burpsuite|fuzz)") {
# Slow down — keep the connection alive but unhelpful
echo_sleep 10; # requires nginx with echo module, or use a Lua snippet
return 200 "";
}
return 200 "OK";
}A simpler "sleep 5 seconds then 200" on known-bad paths costs you almost nothing per hit and significantly reduces scanner throughput. For HTTPS-heavy scanners, the TLS handshake plus the 5-second body delay measurably reduces their rate.
Don't tarpit paths where legitimate users might land — only attacker-only resources.
A few patterns that sound clever but cause problems:
Most teams should stay in detection-only mode for honeypots. Log, alert, optionally block — but don't try to deceive or counter-attack. The signal-to-noise on "anyone hit my honeypot" is so good that you barely need anything else.
Honeypot hit
↓
Structured log → centralized log store
↓
Alert (low-priority) — for tracking only
↓
If repeated from same source within window → escalate
↓
Optional: feed to WAF / fail2ban for blockThe escalation rules separate one-off scanners from focused attackers.
Per honeypot, a small dashboard:
If a honeypot stops getting hits for a long time, attackers may have learned to skip it. Rotate paths / lures occasionally.
For canary tokens specifically: track which token is at which placement, so when one fires you immediately know which surface leaked.
A first honeypot setup, in order of effort:
honeypot.log to your existing log destination.env at a scanner-friendly pathmaxretry=1 for the honeypot (verify Googlebot etc. won't trigger first)Total time: 30–60 minutes. Detection ROI: very high.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.