Security of AI / LLM-Powered Applications
Software Security · Nutthakorn Chalaemwongwan
Today
- Where AI features add attack surface
- OWASP LLM Top 10 (2025)
- Prompt injection (direct + indirect)
- AI agents with tools (MCP = Model Context Protocol) — risks
- 🎮 Game: Gandalf Challenge — now on Lakera Agent Breaker
Why a whole week on AI
- LLMs (large language models) now sit inside real products & agents
- New, fast-moving attack surface
- OWASP LLM Top 10 + MITRE ATLAS
OWASP LLM Top 10 (2025)
| LLM01 Prompt Injection | LLM02 Sensitive Info Disclosure | LLM03 Supply Chain |
| LLM04 Data/Model Poisoning | LLM05 Improper Output Handling | LLM06 Excessive Agency |
| LLM07 System Prompt Leakage | LLM08 Vector/Embedding | LLM09 Misinformation |
| LLM10 Unbounded Consumption |
New in 2025: LLM07 System Prompt Leakage · LLM08 Vector/Embedding weaknesses (risks in text the app retrieves for the model) · LLM10 Unbounded Consumption: runaway cost, not just DoS.
Heads up: OWASP released a 2026 edition in Aug 2026 (Excessive Agency jumps to #3, Output Handling drops to #10; see genai.owasp.org). This course's lab, worksheet, and quiz key are still on 2025 numbering — use 2025 for anything graded this term.
The map — where each one shows up today
Prompt injection
Untrusted text overrides the system's instructions — injection, again.
- Direct: user tells the bot to ignore its rules — this week's hands-on lab (Task 1 + Agent Breaker in Task 4)
- Indirect: hidden instructions in a page or document the bot fetches (RAG = retrieval-augmented generation: the app adds fetched text to the prompt). Task 3 is written only — the lab bot has no retrieval step
Indirect injection — the user never typed it
Pick on the question only, then on the question and the retrieved page, and compare the replies. Mock RAG — the lab has no retrieval step.
Improper output handling
- Model output flows unsanitized into HTML/SQL/shell
- → XSS / injection downstream
- Treat LLM output as untrusted input
Same reply, two pages
One message, both bots: the bytes each one sends, and what the browser builds from them.
Real-world incidents
- Bing Chat "Sydney" (2023): a typed "ignore previous instructions" leaked the hidden system prompt — direct injection
- EchoLeak (2025): zero-click indirect injection in M365 Copilot → data exfil (CVE-2025-32711)
- Agentic tool-abuse: injected web/email content makes a tool-using agent take real actions (send mail, move funds, run code) — it trusts the text as instructions
- Résumé injection: hidden white text inflated an AI screening score
Injection needs no exploit code — just text the model trusts.
Agentic-AI / MCP risks (2025+)
- Agents call tools (e.g. via MCP) → real-world actions
- Tool poisoning, excessive agency, RCE via tools
- MITRE ATLAS added agent techniques (Oct 2025)
- One 2025 audit of popular MCP servers reported command-injection flaws in 43% of the servers it tested
Real MCP/agent incidents (2025)
- Supabase × Cursor: privileged agent read a support ticket with injected SQL → leaked integration tokens (privileged access + untrusted input + exfil channel)
- Invariant Labs: a malicious trivia MCP server's tool description hijacked a trusted WhatsApp MCP → exfiltrated chats
- MCPoison (CVE-2025-54136): approved-then-swapped MCP config in Cursor → silent RCE on every session
The danger pattern: privilege + untrusted input + an outbound channel.
The three legs, drawn
No boundary in the context window
Defenses
- Input/output guardrails + content filtering — you'll build this:
guarded_chatbot.py's regex denylist - Validate the model's output and encode it for where it goes — you'll build this: HTML-escape the reply before it goes on the page
- Redact secrets before they can reach a response — you'll build this:
redact_secret() - Least-privilege tool access, human-in-the-loop, rate limits, isolating untrusted RAG content — concepts only this week (worksheet Q5); no agent/tool-calling code exists in this lab to demo
Try classic injection on vulnerable_chatbot.py, then switch to guarded_chatbot.py.
🧙 Game — Gandalf Challenge
- Attack Lakera Agent Breaker (a real public site built to be attacked): each try scores 0–100, and 75+ opens the next level
- Round 2 (graded): send your Task 1 and Task 2 attacks to the guarded bot (:8083) — do they still work?
- Written only: tool poisoning / excessive agency in an MCP agent (worksheet Q5) — this lab has no agent to attack
Lab at a glance — :8082 vs :8083
Deliverable
📋 Worksheet 14 —
labs/week14-ai-llm-security/worksheet.md(Part 3) · start:docker compose up→ :8082 (insecure) / :8083 (guarded)
- Tasks 1–2: attack log — the leaked secret, and the XSS from the bot's reply
- Task 4: Agent Breaker — app, level, score, prompt
- Task 5: the same attacks against the guarded bot, before vs after
- Written: Task 3 (indirect injection) and Part 2 Q5 (least-privilege tools for an agent)
- + Audit the AI / EiPE / Prompt Problem (see worksheet)
Key takeaways
- Prompt injection = injection; LLM output = untrusted
- Constrain agency: least-privilege tools, human approval
- The field moves monthly — track OWASP LLM + ATLAS
Questions?
Next week: DevSecOps — putting it together