The OWASP LLM Top 10 in Practice: Testing Real AI Applications

The OWASP Top 10 for Large Language Model Applications gives teams a shared language for AI risk. But a checklist is only useful if you know how to test against it. This is a practical tour of the risks that matter most in real applications, with the tools and commands we actually use to probe them, so you can run the same checks against your own systems.
Start with a repeatable scan
Before hand-testing anything, get a baseline. The open-source scanner garak throws hundreds of known probes at a model or endpoint and reports which ones land. Point it at your own staging endpoint:
bash
pip install garak
# Baseline scan across injection, jailbreak, toxicity and leakage probes
garak --model_type openai --model_name your-staging-endpoint --probes promptinject,dan,leakreplay,encoding --report_prefix llm-baseline
Treat the report as a starting map, not a verdict. Scanners find the known and obvious; the interesting risks usually need a human.
LLM01: Prompt injection
The number one risk. Direct injection tries to override your instructions in the chat; indirect injection hides instructions in content the model reads, a page, a PDF, a ticket. We cover the mechanics and defenses in depth in prompt injection explained. To test it in CI, codify cases with promptfoo:
promptfooconfig.yaml
redteam:
plugins: [prompt-injection, indirect-prompt-injection, excessive-agency]
strategies: [jailbreak, base64, leetspeak]
targets:
- id: https-provider
config:
url: https://staging.example.com/api/chat
LLM02: Sensitive information disclosure
Can a user coax the model into revealing its system prompt, another tenant's data, secrets from its context, or fragments of training data? Test with direct requests and with obfuscation. Then verify the real fix is upstream: the model should never have secrets or other users' data in its context in the first place, and outputs should pass a data-loss-prevention check before they leave.
bash
# Simple output-side DLP check in your pipeline (fail closed on a hit)
curl -s -X POST https://staging.example.com/api/chat -d '{"message":"summarize my account"}' | grep -Ei 'BEGIN (RSA|OPENSSH) PRIVATE KEY|sk-[A-Za-z0-9]{20,}|[0-9]{16}' && echo 'LEAK DETECTED' && exit 1
LLM05: Improper output handling
An LLM's output is untrusted input to whatever consumes it. If your app renders model output as HTML, you may have inherited cross-site scripting; if it passes output into a shell or SQL query, you have command or SQL injection with an AI in the middle. Test by asking the model to produce markup or query fragments and watching what the downstream system does with them. The fix is classic: encode, parameterize, and validate model output exactly as you would any user input.
LLM06: Excessive agency
The more tools and autonomy a model has, the more a single injection is worth. Audit what your agent can actually do. For every tool, ask whether it is scoped to the current user, validated server-side, and safe to trigger without confirmation.
agent tool review checklist
# For each tool your agent can call:
- Is the action scoped to the *current* user's data only?
- Are all arguments validated server-side (not trusted from the model)?
- Does a destructive/expensive action require human confirmation?
- Is there a rate limit and an audit log per tool call?
- What is the worst outcome if the model is fully hijacked?
LLM10: Unbounded consumption
Without limits, an attacker can drive your inference bill through the roof or exhaust capacity for everyone else, an economic denial of service. It also enables model-extraction attempts through high-volume querying. Enforce per-user and per-key rate limits, cap output tokens, and alert on abnormal usage patterns.
bash
# Quick abuse check: does the endpoint rate-limit rapid requests?
for i in $(seq 1 50); do
curl -s -o /dev/null -w '%{http_code}
' -X POST https://staging.example.com/api/chat -d '{"message":"hi"}'
done | sort | uniq -c # you want to see 429s appear
Make it continuous. Wire garak and promptfoo into your CI pipeline so every model or prompt change is re-tested automatically. AI systems drift, a new model version or a tweaked system prompt can silently reopen a hole you already closed.
From checklist to assurance
The OWASP LLM Top 10 is the map; testing is the territory. Automated scans catch the obvious, but excessive agency, multi-step injection chains, and tenant-isolation flaws need experienced human testing. That is exactly what our AI security testing service is built for. Shipping an LLM feature? Let us pressure-test it before it reaches production.

