Half Asleep and the Servers Are Still Running
Testing AI-managed incident response in a home lab
The Setup
It was late, and I was half asleep, planning a side project: a second brain system where I could fire off links and voice notes to Telegram and have something sort them for later recall. Classic midnight engineering daydream.
I figured n8n would be perfect for this, so I pulled up my instance to check what version I was running.
It was behind. Way behind.
Here's the thing though: I'd been tracking n8n vulnerabilities after security Twitter lit up on January 6th about a new one called CVE-2026-21858, nicknamed "Ni8mare." CVSS 10.0. Unauthenticated file read. The kind where attackers can just pull credentials off your server without logging in.
So I asked Gemini: "Is this version vulnerable?"
It was.
Now, normally for a home lab, I'd just kill the exposure, run the upgrade, and move on. No postmortem. No forensic analysis. It's a lab—who writes incident reports for their own infrastructure?
But I'd been building out a multi-agent AI system, and this felt like the perfect stress test. A real security incident. Real CVEs. Real credentials at risk. Could I hand this to my AI agents and have them run a proper incident response while I went to bed?
Time to find out.
The First Call: Kill the Tunnel
I killed the Cloudflare tunnel. Not panic—just prudent. The instance had been running an old version for three months, but the vulnerabilities themselves were fresh. The exposure window was measured in days, not months.
sudo systemctl stop cloudflared
Tunnel down. Instance isolated to LAN only. Clock ticking on what came next.
Handing It to Bob: Initial Incident Response
Here's where this story gets interesting.
I handed the whole thing to Bob—my AI assistant built on Claude Code. Bob is one of several AI agents I've set up, all named after characters from the Bobiverse novels (a sci-fi series about a guy who gets uploaded into a Von Neumann probe and makes copies of himself to explore the galaxy). The naming isn't just whimsy; each agent has a specialized role that matches their namesake's personality.
"Run this like full incident response," I told Bob. "Forensics first. I need to know if we got hit."
Bob spun up Mario—another AI agent, my engineer specialist—for initial triage. Not the upgrade yet, the investigation. Mario's job was to answer one question: were we compromised?
What Mario Found: The Attack Surface Analysis
Mario started with the fundamentals: what attack vectors were actually present in this instance?
The CVEs we were dealing with:
| CVE | Nickname | CVSS | Type | Published | Days Exposed | |-----|----------|------|------|-----------|--------------| | CVE-2026-21858 | Ni8mare | 10.0 | Unauthenticated file read | Jan 6, 2026 | ~6-7 | | CVE-2025-68613 | — | 9.9 | Expression injection RCE | Dec 19, 2025 | ~25 | | CVE-2025-68668 | N8scape | 9.9 | Python sandbox bypass | Dec 26, 2025 | ~18 |
An important distinction: the instance had been running an old version for months, but it wasn't vulnerable until these CVEs were published. The maximum real exposure window was about 25 days, starting December 19th.
Mario's attack surface assessment:
| CVE | Exploitable? | Why | |-----|-------------|-----| | Ni8mare (CVE-2026-21858) | NO | Requires Form Trigger with file upload. Our Form Trigger used dropdowns. | | Expression injection (CVE-2025-68613) | NO EVIDENCE | 24 workflows analyzed, zero malicious expression patterns | | N8scape (CVE-2025-68668) | NO | Requires Python Code nodes. We had zero. |
Configuration luck—that's what saved us. Not security controls, just the way I happened to build workflows.
Deeper Dive: Homer and Riker on Research
While Mario handled the initial forensic sweep, Bob parallelized the vulnerability research by spinning up two more agents: Homer (my strategist) and Riker (my researcher). This is what the multi-agent setup is for—running parallel workstreams while you're doing something more useful than waiting.
Riker compiled the IOC detection approach:
For Ni8mare (CVE-2026-21858), the key indicators were:
- Form Trigger nodes with
fieldType: "file"orfieldType: "multipleFiles" formEndingnode in the same workflow as Form Trigger- Webhook logs showing POST requests with
Content-Type: multipart/form-data - Filesystem reads targeting
/home/node/.n8n/.envor/home/node/.n8n/config
For the expression injection (CVE-2025-68613):
- Expressions containing
process.mainModule.require - Use of
child_processorfsmodules in expressions eval()orFunction()constructors in node parameters- Constructor.constructor patterns for sandbox escape
For N8scape (CVE-2025-68668):
- Python Code nodes with
__import__('os')or__import__('subprocess') - Use of
eval(),exec(),compile()in Python nodes - Attempts to access
sys.modulesorglobals()
Homer outlined remediation best practices:
- Upgrade path: v1.114.3 to v2.4.0 (skip intermediate versions)
- Encryption key rotation post-upgrade
- Secrets migration from docker-compose.yml to .env file
- OAuth token refresh procedures
This research armed the forensic phase with specific detection signatures.
The Forensic Methodology
This is where the security professionals in the audience might find the details useful. The investigation was systematic, SQL-based, and designed to detect specific attack patterns. If you're running n8n and want to check your own instance for these CVEs, these queries are reusable.
Detection Query: Ni8mare (CVE-2026-21858)
-- Identify Form Trigger workflows with file upload capability
SELECT
w.id,
w.name,
w.active,
w.createdAt,
w.updatedAt,
w.nodes::jsonb
FROM workflow_entity w
WHERE w.nodes::text LIKE '%formTrigger%'
ORDER BY w.updatedAt DESC;
Result: One Form Trigger workflow found ("Contact Form"). Deep inspection showed form fields: Name (text), Email (text), Service Interest (dropdown). No file upload field. No formEnding node.
Not exploitable.
Detection Query: N8scape (CVE-2025-68668)
-- Find Python Code nodes
SELECT
w.id,
w.name,
w.active,
w.nodes::text
FROM workflow_entity w
WHERE w.nodes::text LIKE '%"type":"n8n-nodes-base.pythonCode"%'
OR w.nodes::text LIKE '%python%'
ORDER BY w.updatedAt DESC;
Result: Zero Python Code nodes across all 24 workflows. JavaScript only.
Not exploitable.
Detection Query: Expression Injection (CVE-2025-68613)
-- Search for malicious expression patterns
SELECT
w.id,
w.name,
w.nodes::text
FROM workflow_entity w
WHERE w.nodes::text ~* '(process\.mainModule\.require|child_process|fs\.readFile|fs\.writeFile|eval\(|Function\(|constructor\.constructor|import\()'
ORDER BY w.updatedAt DESC;
Result: Zero matches. Benign expressions only (date formatting, string manipulation).
No evidence of exploitation.
User Account Audit
-- Check for unauthorized user accounts
SELECT
id,
email,
"firstName",
"lastName",
"createdAt",
"updatedAt",
disabled
FROM "user"
ORDER BY "createdAt" ASC;
Result: Single user account (mine). Created November 14, 2024. No additional accounts, no disabled accounts, no evidence of account takeover.
Workflow Modification Analysis
-- Look for suspicious workflow modifications
SELECT
w.id,
w.name,
w.createdAt,
w.updatedAt,
(w.updatedAt - w.createdAt) as age_since_creation
FROM workflow_entity w
WHERE w.updatedAt > w.createdAt
ORDER BY w.updatedAt DESC
LIMIT 20;
Result: Most recent modification was December 18, 2025, twenty-four days before the investigation. All modifications aligned with known legitimate work. No suspicious after-hours modifications. No mass workflow modifications indicative of automated attack.
The Verdict: Configuration Luck (With Caveats)
After comprehensive analysis, the determination was clear: NOT COMPROMISED.
But here's the honest assessment. While Ni8mare (the CVSS 10.0) had only 6-7 days of exposure and our configuration made it unexploitable anyway, the December 19th CVE had about 25 days of exposure. That's a longer window. For a lab environment, I'm comfortable with the analysis. For production, I'd want additional compromise checking: deeper log analysis, credential rotation as a precaution, maybe network traffic review for that 25-day period.
The configuration luck is real though. The only reason attackers couldn't exploit these was configuration choices I'd made for unrelated reasons:
- I used a dropdown instead of a file upload in my contact form
- I preferred JavaScript over Python for code nodes
- I was the only user, so the authenticated RCE vectors required prior compromise
That's not security. That's configuration luck.
If I'd built one workflow differently—say, a file upload form for document processing—we'd be having a very different conversation. Attackers were using Ni8mare specifically to pull credentials out of n8n instances. My instance had 37 credential objects: API keys, OAuth tokens, database connections. All of it would have been theirs.
The Remediation: Set It and Forget It
With forensics complete and the "not compromised" verdict in hand, I made a call: hand the upgrade to Mario and go to bed.
This is what I call "YOLO mode"—let the AI agent work while you sleep, validate in the morning. The tunnel was already dead, so the risk was contained. If Mario broke something, I'd fix it with coffee in hand.
What Mario actually did overnight:
- Backed up everything (database: 1.28MB, 64 workflows: 547KB, docker-compose.yml)
- Prepared a hardened configuration:
- Secrets migrated to .env file (chmod 600)
- Port binding changed from
0.0.0.0:5678to127.0.0.1:5678 - N8N_RUNNERS_ENABLED=true (v2.x security feature)
- Pulled n8n 2.4.0 image
- Hit an encryption key validation issue (n8n 2.x behavior change stores key in
/home/node/.n8n/configand validates against env var) - Figured it out himself and fixed it by updating the config file in the docker volume
- Ran 29 database migrations successfully
- Verified healthy containers, HTTP 200, correct port binding
Morning validation: I woke up, checked the logs, and verified the upgrade completed successfully. The only thing that needed my hands on keyboard was the Cloudflare tunnel key. I'd revoked the old one when I killed the tunnel, so I had to generate a new one.
Five minutes of actual work from me. That was the morning validation—not the upgrade itself. Mario handled that overnight.
Lab Rules Apply
Context matters: this is my lab. Not production. Not a client environment. Proof-of-concept territory.
I'd never let an AI agent run a security incident on production systems without validation at every step. In a real environment, you want:
- Human approval gates
- Staged rollouts
- Rollback plans
- Multiple eyes on changes
But for a home lab? The rules are different. I can experiment with trust boundaries. I can see what happens when you give an agent enough rope to actually solve problems.
And what happened was: it worked.
The Interesting Part
The interesting part isn't that AI can follow a runbook. Any decent automation tool can do that.
The interesting part is that I ran a full security incident response while half asleep.
I made the critical decisions:
- Kill the tunnel immediately (judgment call on risk)
- Delegate to Bob (trust decision on capability)
- Scope the investigation (forensics before remediation)
- Confirm no compromise, then greenlight the overnight upgrade
- Provide the new Cloudflare key (credential management)
The AI handled the complexity:
- Attack surface analysis against three CVEs
- SQL-based forensic detection queries
- IOC compilation and signature matching
- Full upgrade with encryption key rotation
- Security hardening (port binding, secrets management)
When I woke up, I had:
- Forensic analysis complete with specific CVE coverage
- "Not compromised" determination with evidence
- Upgrade deployed (1.114.3 to 2.4.0)
- Security hardened (secrets in .env, localhost binding)
- Full documentation generated
And I barely touched a terminal.
What's Next: Production Migration
The n8n instance is moving into production now. The lab proved the pattern works. But I'm noting that the December 19th CVE's 25-day exposure window warrants extra caution—additional credential rotation or deeper monitoring review before I consider this fully closed.
The "not compromised" verdict is high confidence for the CVSS 10.0 Ni8mare attack. For the older CVEs with longer exposure windows, confidence is still high, but prudent ops means you don't assume. You verify.
What This Proves
The security situation was accidental. The test was deliberate. I stumbled into a real incident while planning a completely different project, recognized it as the perfect opportunity to stress-test my AI infrastructure, and handed it off.
For security professionals:
- The forensic methodology was systematic and SQL-based
- IOC detection covered all three CVEs with specific signatures
- The "configuration luck" analysis is the honest answer, not security controls
- Real exposure windows: 6-7 days for the CVSS 10.0, up to 25 days for the older CVEs
- Credential exposure assessment included full inventory and rotation recommendations
For lab environments:
- You can delegate complex incident response to capable agents
- Confirm no compromise first, then set remediation running overnight
- Validate in the morning
- Maintain human control at decision points
For production:
- You'd want validation layers built in
- Human-in-the-loop for anything touching credentials or network exposure
- Staged changes with rollback capability
- But the foundation is there
The idea that you can offload infrastructure complexity to AI agents while you handle strategy and judgment—that's not theoretical anymore. I watched it work.
The Artifacts
If you want to see the actual outputs:
Full Postmortem: n8n/security/n8n-security-postmortem-2026-01-12.md
800+ lines covering timeline, vulnerability context (with CVSS breakdowns), forensic methodology, detection queries, credential exposure assessment, root cause analysis, and recommendations. Includes appendices with reusable SQL queries, log analysis patterns, and agent research briefs.
Upgrade Log: n8n/UPGRADE-LOG.md
Mario's step-by-step documentation including reconnaissance, backup verification, security improvements applied, encryption key mismatch resolution, and final health checks.
All generated by agents. I pointed them at the problem and went to sleep.
Takeaways
For security teams:
- This incident demonstrates AI-augmented incident response at the home lab scale
- The forensic queries are reusable for n8n CVE detection
- "Configuration luck" is not a security posture—it's a near-miss report
- Proactive CVE monitoring caught this before exploitation
- Exposure windows matter: the instance was outdated for months, but vulnerable for days
For the curious:
- AI-managed infrastructure is real and it works
- Lab environments are where you prove patterns before production
- Trust is built incrementally (this was months of working with these agents)
For the skeptical:
- I didn't "trust blindly"—I confirmed no compromise before setting the upgrade running
- Human judgment stayed in the loop for decisions that mattered
- This was a near-miss that worked out; configuration luck was involved
For the pragmatic:
- The future isn't AI replacing humans in security ops
- It's AI handling execution complexity while humans make strategic calls
- The half-asleep test is actually a decent stress test for autonomous systems
Written January 13, 2026 After successfully not getting pwned And proving the AI incident response workflow actually works