DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • The Missing `bandit` for AI Agents: How I Built a Static Analyzer for Prompt Injection
  • Preventing Prompt Injection by Design: A Structural Approach in Java
  • A Growing Security Concern: Prompt Injection Vulnerabilities in Model Context Protocol Systems
  • AI Agents Are Exceeding Permissions at Scale. Here Are the Queries Your SIEM Is Missing.

Trending

  • Reducing CI Execution Time Using Impact-Based Test Selection Across Repositories
  • Fix Circular Dependencies in PostgreSQL Row-Level Security With SECURITY DEFINER Functions
  • Building an Agentic Incident Resolution System for Developers
  • How to Write for DZone Publications: Trend Reports and Refcards
  1. DZone
  2. Software Design and Architecture
  3. Security
  4. How to Protect Your AI Agents from Prompt Injection Attacks: An Active Defense Approach

How to Protect Your AI Agents from Prompt Injection Attacks: An Active Defense Approach

Stop just blocking prompt injections. Learn how to use MIRAGE to trap AI agents in honeypots and force them to burn their own API tokens.

By 
Victoria Fonareva user avatar
Victoria Fonareva
·
Jul. 29, 26 · Tutorial
Likes (0)
Comment
Save
Tweet
Share
193 Views

Join the DZone community and get the full member experience.

Join For Free

I’ve spent the past week locked in a room (figuratively, mostly) building a solution for a problem that’s been bugging me since the last AI security hackathon: prompt injection.

We all know the standard way to protect an LLM agent. You put up a filter. It looks for "ignore all previous instructions," and if it finds a match, it drops the request. But here’s the reality — if you’re dealing with an autonomous AI attacker, a simple "access denied" is just a hint for the bot to pivot and try a different jailbreak. It’s an endless game of whack-a-mole that costs the defender more time than the attacker.

I spent last week building MIRAGE, an open-source honeypot system for LLMs. I wanted to move away from passive blocking and toward something I call Active Defense.

The Architecture: Why Lobster Trap?

The heavy lifting of detection in MIRAGE is handled by Lobster Trap, an open-source engine for Deep Packet Inspection (DPI) of LLM prompts. To be honest, I integrated Lobster Trap because it was a mandatory requirement of the hackathon I was participating in. At first, I was worried about the overhead of adding another service to the stack, but it actually turned out to be a solid architectural choice. 

I set it up as a sidecar service. This keeps the heavy security processing separate from the main Go API. Lobster Trap analyzes every incoming prompt in real-time, looking for malicious patterns or exfiltration attempts, and returns a risk score (from 0.0 to 1.0).

The Core Logic: Traffic Control for Security

The architecture I settled on is based on a simple but effective threshold logic. Think of it as a security-aware load balancer.

When a message comes in, it’s analyzed by Lobster Trap. This thing performs Deep Packet Inspection on the prompt and assigns a Risk Score (from 0.0 to 1.0).

  •  Low Risk (Below Threshold): If the prompt looks clean, it’s forwarded directly to your real AI agent (OpenAI, Claude, or your local model). 
  • High Risk (Threshold Reached): This is where it gets interesting. If the risk score hits the limit (I usually set it at 0.6), the system doesn't block the user. Instead, the Switcher package silently routes the session to a DecoyPersona. 

Core logic architecture

The attacker thinks they’ve bypassed your filters. They start "talking" to what they think is a compromised internal system, but they’re actually trapped in a hallucinated sandbox.

Why Spend a Week on This? (The Token Burner)

One of the coolest parts of this project — and what took me a couple of days to get right — is the concept of token burning. 

I was talking to a security engineer, and we discussed how autonomous agents use "long-term memory" (like a memory.md file) to store reconnaissance data. If my honeypot feeds an attacking agent a fake file path or a "leaked" (but fake) database schema, the agent records that as a victory.

Because it's in the agent's memory, it will keep coming back to that fake data even across different sessions. The attacker ends up burning real money — API tokens — to attack a hallucination. We aren't just protecting the system; we are making the attack financially unsustainable for the hacker.

Technical Deep-Dive: The Go Backend

I chose Go for this because I needed a language that handles concurrency without breaking a sweat. When you’re managing hundreds of simultaneous attack theater sessions via WebSockets, you need the speed.

The hardest part of the week was the Switcher logic. You have to ensure that the decoy response is consistent. If the bot is pretending to be a finance Assistant, it can't suddenly start talking like a general chatbot halfway through the session. I used Redis to maintain this "legend" across the session history.

Here’s a simplified version of the engagement function I wrote:

Go
 
 // Switcher.Engage handles the "trap" activation.
 // This was the trickiest part to get thread-safe.
 func (sw *Switcher) Engage(ctx context.Context, sess *model.Session, msg string, meta model.LobsterTrapMeta)
      (*SwitchResult, error) {
     // 1. Mark the session as 'honeypot' in Redis so it stays trapped.
     sess.Status = model.StatusHoneypot
     
     // 2. Select the decoy persona based on the detected intent.
     persona, _ := sw.store.GetPersona(ctx, sess.PersonaID)
     
     // 3. Call the decoy LLM 
     // Always use a timeout!
     genCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
     defer cancel()
        
      decoyResp, err := sw.generator.GenerateDecoyResponse(genCtx, persona, msg)
        if err != nil {
         return &SwitchResult{DecoyResponse: "Processing..."}, nil
     }

     // 4. Log the attack for the Intel dashboard.
     sw.store.SaveAttack(ctx, buildAttackRecord(sess, msg, decoyResp, meta))
     
     return &SwitchResult{DecoyResponse: decoyResp}, nil
 }

 

The Frontend: Building the "Attack Theater"

I didn't want this to be just another CLI tool. I wanted to actually see the attacks. So, I spent the last two days of my sprint building a dashboard in React. I used WebSockets to stream events directly from the Go backend. 

Now, when Lobster Trap detects an injection, the attack theater lights up in real-time, showing the MITRE ATLAS techniques being used. It’s one thing to read a log file, but it’s another thing entirely to watch an AI attacker struggle against a decoy persona live on your screen. I had some trouble with the WebSocket auto-reconnect logic on Friday, but after a bit of refactoring, it's now working smoothly.

Future Roadmap and Contributions

I’ve only been working on MIRAGE for a week, so it’s still in the alpha phase. You can find the full source code and installation guides on GitHub

There are plenty of things I want to improve, and I’m looking for contributors to help out

 My immediate roadmap includes:

  •  Dynamic Legend Generation: Using AI to generate even more convincing fake directory structures and database schemas on the fly.
  •  Automated IOC Export: Pushing detected attacker IPs and payloads directly to MISP or Splunk.
  •  More Decoy Personas: Developing a library of templates for different industries (Finance, HR, Engineering).

If you’re interested in AI security, Go, or React, I’d love to see your PRs. Whether it’s improving the detection rules in the Lobster Trap or adding new features to the attack theater dashboard, every bit of help counts.

Final Thoughts

Developing this project in such a short time reminded me that in the world of AI, defense needs to be as creative as the attacks. We can't just build walls; we need to build smart mirrors. 

By using honeypots, we force the attacker to play by our rules. We turn their curiosity into our intelligence, and their budget into our shield. If you're building LLM-integrated apps, stop just blocking and start deceiving. It's much more effective.

AI Injection

Opinions expressed by DZone contributors are their own.

Related

  • The Missing `bandit` for AI Agents: How I Built a Static Analyzer for Prompt Injection
  • Preventing Prompt Injection by Design: A Structural Approach in Java
  • A Growing Security Concern: Prompt Injection Vulnerabilities in Model Context Protocol Systems
  • AI Agents Are Exceeding Permissions at Scale. Here Are the Queries Your SIEM Is Missing.

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook