TL;DR
Our admin panel at /admin had no authentication. Anyone who guessed the URL could view all user data, modify settings, and delete accounts. A kind stranger found it and emailed us before anything bad happened. We immediately added authentication, moved to a non-guessable URL, and implemented proper access controls.
We thought we were being clever by not linking to the admin panel from anywhere on the site. Security through obscurity, right? Wrong. Very, very wrong.
The Email That Changed Everything
"Hi, I was poking around your site and noticed your admin panel at /admin doesn't require any login. I can see a list of all users with their email addresses, and there are buttons to delete accounts. You should probably fix this. I didn't touch anything, just wanted to let you know."
My heart stopped. I rushed to check, and there it was - our entire admin dashboard, completely exposed. User emails, subscription statuses, internal notes, delete buttons, everything. Zero authentication required.
How Did This Happen?
The admin panel was built during a late-night coding session. We planned to add authentication "later." Later never came. We deployed it, it worked, and we moved on to other features.
The thought process was dangerous:
- "Nobody knows the URL exists"
- "We don't link to it anywhere"
- "We'll add auth before we launch properly"
- "It's just a small internal tool"
But attackers don't need links. They have tools that scan for common paths like /admin, /dashboard, /manage, /internal, and hundreds of others.
What Was Exposed
- Complete user list with email addresses
- User subscription and payment status
- Internal notes we'd written about users
- Ability to modify any user's account
- Delete buttons that actually worked
- System configuration settings
The Immediate Fix
We dropped everything and implemented authentication within the hour:
// middleware/adminAuth.js
export function requireAdmin(req, res, next) {
const user = req.session?.user;
if (!user) {
return res.redirect('/login?redirect=/admin');
}
if (user.role !== 'admin') {
return res.status(403).send('Access denied');
}
next();
}
// routes/admin.js
router.use(requireAdmin); // Protect all admin routes
We also moved the admin panel to a randomly generated path that couldn't be guessed:
// Instead of /admin
app.use('/internal-mgmt-7f3k9x2m', adminRoutes);
Defense in Depth
After the immediate panic subsided, we implemented proper layered security:
- Authentication: Login required for all admin routes
- Authorization: Role-based access control (RBAC)
- IP Restrictions: Admin access only from office/VPN IPs
- Audit Logging: Every admin action logged with user and timestamp
- Two-Factor Auth: Required for all admin accounts
- Rate Limiting: Prevent brute force on admin login
// IP whitelist middleware for admin
const allowedIPs = process.env.ADMIN_ALLOWED_IPS?.split(',') || [];
function ipWhitelist(req, res, next) {
const clientIP = req.ip || req.connection.remoteAddress;
if (!allowedIPs.includes(clientIP)) {
console.warn(`Admin access denied from ${clientIP}`);
return res.status(403).send('Access denied');
}
next();
}
- Never rely on obscurity for security - attackers will find hidden URLs
- Implement authentication BEFORE deploying any admin functionality
- Use defense in depth - multiple layers of protection
- Add audit logging to track who accesses sensitive areas
- Regularly scan your own site for exposed endpoints
- "We'll add security later" means "We'll get hacked eventually"
What Could Have Happened
We got incredibly lucky. The person who found our admin panel was ethical. They could have:
- Downloaded our entire user database
- Deleted all user accounts
- Modified subscription statuses to steal service
- Used the user list for phishing attacks
- Sold the data on dark web forums
- Held us ransom for the data
Instead, they sent a polite email. We owe them more than we can express.
Is changing the admin URL to something random enough?
No. It's a useful additional measure, but never your only defense. URLs can leak through browser history, referer headers, or employee mistakes. Always combine with proper authentication.
::
How do attackers find hidden admin panels?
They use automated scanners that try thousands of common paths (/admin, /administrator, /manage, /backend, etc.). Some also use dictionaries of leaked paths from other sites or check JavaScript files for route definitions.
What's the minimum security for an admin panel?
At minimum: strong authentication (password + 2FA), proper authorization (role checks), HTTPS only, audit logging, and rate limiting. IP restrictions and non-standard URLs add extra layers.
::
Scan your vibe coded projects for exposed admin panels and authentication issues.
Check Your Vibe Now