---
title: 'Fake Admin, Real Trap: NotTodayHoney for Laravel'
description: "A Laravel package to detect malicious actors through three alert levels, and waste their time."
pubDate: 'Apr 19 2026'
heroImage: '../../../assets/not-today-honey-hero.png'
icon: '/img/nottodayhoney-sticker.svg'
tags: ['Laravel', 'PHP', 'Security', 'Blue Team']
lang: 'en'
---

Honeypots are usually talked about in the context of web forms: a hidden field that catches bots. Useful, but not what I was after. What I wanted was something more fundamental, **detecting someone actively trying to harm a system, and wasting their time doing it**.

The honeypot idea is the same: lure with something attractive. But rather than filtering spam, I wanted to identify malicious intent and react accordingly.

---

## Rethinking the honeypot

Most Laravel honeypot packages focus on form bots. That's a real problem, but it's a small slice of the threats a web project actually faces.

Three attacker profiles interested me more:

**Automated scanners**, tools like `nuclei` or `nmap` that sweep the internet looking for known attack surfaces. They probe endpoints like `/wp-admin`, `/phpmyadmin`, or `readme.txt` files that reveal vulnerable version numbers. They're not targeting anyone specifically, they're harvesting information at scale.

**Opportunists**, people who find an interesting endpoint and try to exploit it. A visible fake admin panel, and they start trying common credential combos: `admin/admin`, `root/root`. They're looking for an unlocked door.

**Targeted attackers**, those who know the system and are deliberately trying to compromise it. Using a known username, a password from a data breach, or a combination that shouldn't have been publicly accessible.

NotTodayHoney grew out of this reading. I wanted to give development teams, small projects and large applications alike, a simple, code-close solution that detects these three levels of intent and reacts accordingly.

---

## What NotTodayHoney does

Full documentation is available at [vinksyunit.github.io/NotTodayHoney](https://vinksyunit.github.io/NotTodayHoney/getting-started.html).

### Traps that look like the real thing

The package deploys fake login endpoints, *traps*, that mimic well-known interfaces:

- **WordPress**: `/wp-admin/wp-login.php` with a spoofed version number, REST API discovery endpoints, user listings, and plugin `readme.txt` files to attract CVE scanners
- **phpMyAdmin**: `/phpmyadmin` with session cookies that mimic a real instance, even before authentication
- **Generic Admin**: `/admin/login` with a configurable title to match whatever attackers are searching for

These endpoints are never reached by legitimate users. Every visit is therefore a signal.

### Three detection levels

Collected events generate progressive alerts:

| Level | Trigger | Block duration | Severity |
|-------|---------|----------------|----------|
| **Probing** | 3 visits in 24h | 20 minutes | Info |
| **Intrusion Attempt** | 1 login attempt | 24 hours | Warning |
| **Attacking** | Known credentials / compromised password | 30 days | Critical |

An IP visiting `/wp-admin` three times in a day is probably an automated scanner, a light alert is enough. An IP submitting credentials is a more serious threat. An IP using a password from a known data breach deserves a 30-day block and a critical alert.

### Wasting the attacker's time

All trap responses are delayed by a minimum of 1000ms, not to slow down legitimate users (who should never reach these endpoints), but to prevent an attacker from fingerprinting a honeypot by its response time.

On login traps, you can configure a `fake_success` response: the attacker sees an empty fake dashboard and believes they've gained access. They keep exploring, keep wasting time, while every action is logged.

### Setup

```bash
composer require vinksyunit/not-today-honey
php artisan vendor:publish --tag="not-today-honey-config"
php artisan vendor:publish --tag="not-today-honey-migrations"
php artisan migrate
```

Requirements: PHP 8.4+ and Laravel 12+.

### Block without giving yourself away

Once IPs are marked as threats, the `HoneypotBlockMiddleware` handles blocking them. The recommended approach is to **not apply it globally**. If a blocked IP gets a 403 on the homepage, it immediately knows it's been identified and changes tactics.

The goal is the opposite: let the attacker browse public pages freely, but silently block them on anything that matters.

```php
// bootstrap/app.php — targeted protection only
Route::middleware('nottodayhoney.block')->group(function () {
    Route::post('/login', [AuthController::class, 'store']);
    Route::post('/register', [RegisterController::class, 'store']);
    Route::prefix('/api')->group(function () {
        Route::post('/tokens/create', ...);
        Route::post('/password/reset', ...);
    });
    Route::prefix('/admin')->group(function () {
        // All sensitive admin routes
    });
});
```

Result: the attacker can browse the site, everything looks normal. The moment they try to reach anything critical, the request is blocked. They don't know why, they don't know when it happened, and every new attempt is logged.

---

## One more tool in the Blue Team stack

NotTodayHoney is a **detection** tool, not a prevention one. It doesn't block network packets, enforce firewall rules, or fix application vulnerabilities. What it does is surface behavioral signals and alert on them.

That's its exact role in a Blue Team stack, and it doesn't claim to be more than that.

Serious defense is layered. NotTodayHoney sits in the application layer, alongside a reverse proxy or WAF at the traffic edge, IP blocking at the network level, strong authentication and a reduced attack surface, injection-focused code reviews, and penetration testing that surfaces what honeypots can't see.

What NotTodayHoney brings is visibility into real behavior, not simulations. The credentials submitted on a fake `/wp-admin` are the actual credentials someone tried. That's information no other tool in the stack collects.

For small projects, it's often the first piece of operational security monitoring you can deploy without budget or complex infrastructure. For larger ones, it's an additional signal source that feeds into an existing SIEM.

Easy to install, close to the code, low cost, that's exactly what I had in mind when I wrote it.
