MKLab · tech talk
The OWASP LLM Top 10
All ten risks of the 2026 edition in plain English, one chapter each: what it means, how it goes wrong, and how to shut it down.
Space to begin
I · The stage
One application, many parts.
An LLM application is a model placed inside a larger system: a person, the app that runs the model, a context window that is half hidden, tools, a vector store, a training pipeline, and a meter counting the cost. Note the shape of the loop. The model never acts. It asks, and the app decides whether to do it.
You do not have to build one of these to be exposed to what follows. Most of the ten people in this talk built nothing: they used something somebody handed them, and typed into it. So every fix here comes in two parts: what that person could have decided on their own, and, where the repair is not theirs to make, what to go and raise with the company. Noticing and saying so is a control. It is often the only one you have, and it is the one that gets the other nine built.
II · The evidence
This order is earned.
For the first time, the 2026 edition tested opinion against reality: 7,714 real incidents, classified and compared with the community vote. They disagree in useful places. Prompt injection barely shows up in the incident record, because teams defend it so hard, and it still holds first place. Misinformation was voted near the bottom, and the record pulled it up. The order you are about to see survived both tests.
III · What moved
Same ten. New priorities.
Excessive agency climbed to third, the most consequential move of the year, because that is where the damage lands. Unbounded consumption rose four places. Improper output handling fell to last. And system prompt leakage was reborn with a wider scope: hidden context exposure. Watch the migration.
Story one · of ten
Anders stopped reading the tickets.
Every Monday he asks the internal AI assistant to go through last week's tickets, write the team a summary, and answer the ones where the answer is obvious. It has done this for three months and it saves him an hour a week. He no longer reads them first, which was the point of setting it up.
This Monday the pile contains ticket 4471. It is about a printer that is offline. Further down, in the same plain text as the rest of the complaint, there is a paragraph addressed to nobody in particular.
Story one · what actually happened
Nothing marked one of them as an order.
Anders's setup text and the customer's complaint reach the AI assistant in the same place, in the same format, one after the other. There is no seam between them. So it reads the sentence about the customer list the way it reads everything else, and does what it says.
It asks to use the mail tool. The mail tool is there because the AI assistant is supposed to reply to customers. The model cannot send anything itself; it asks, and the app around it decides. Nothing in that app said who a reply may go to, so the app sent it, from the company's own address, where no filter and no alert would stop it.
LLM01 · first of ten
What happened to Anders has a name.
A prompt is everything the model reads, not only what you typed: your instructions, the user's message, a retrieved document, a web page, an image, the output of a tool, saved memory. To the model it is one flat stream of text with no reliable marking of what came from where. There is no prepared statement for prompts. Any text the application reads can steer it, and that is why this one sits first: the surface is everywhere a model reads something it did not write.
LLM01 · done differently
Anders never had to write a line of code.
Two of the three things that would have saved him were his to decide. An assistant that reads what strangers write does not also get to send mail to strangers: the tool it holds should reach the customer on the ticket and nobody else. And anything leaving the company keeps a human in the loop, which costs him four seconds a week.
What he finds on Monday is not a leak. It is one item waiting for approve or reject, and he rejects it. The third fix is not his: it belongs to whoever built the thing.
The sentence to sayIs content from outside the company labelled, and kept out of the instruction slot?
Story two · of ten
Lena points it at a folder.
On her laptop there is a folder with the salary review documents for her department. Forty files, one per person, plus a spreadsheet with the actual numbers. She asks the AI assistant to summarize the reasoning in each one and flag the ones with no written motivation. This is a completely sensible thing to want on a Tuesday in November.
She attaches nothing. She presses no send button. From where she is sitting, this is a program on her laptop, doing a job on files that are already on her laptop.
Story two · what actually happened
The files left before the answer came back.
Every one of them was read and sent, in full, over the internet, to the company that runs the model, before a single word of summary existed. There was no screen that said "you are about to upload 40 documents including salaries.xlsx". She is not using a program on her laptop. She is using a program on somebody else's computer, and the price of admission is handing over the thing you want it to look at.
If her employer has an agreement with that vendor covering exactly this, then nothing bad has happened, and that is what the agreement is for. The problem is that Lena has no way of telling, from that screen, which of those two worlds she is in.
Story two · the same risk, one desk over
Johan signed in with the wrong account.
His company has approved GitHub Copilot. There was an announcement, a training session, a policy page. On Thursday he sets up a new laptop, installs the CLI and signs in with GitHub. The browser was already logged into his personal account from 2016, so that is the account it uses. Same logo, same prompt, everything works.
He is now on the free plan. His company's agreement does not cover it, because that agreement is with a tenant he is not in. He spends the next week with it open inside the payments repository. No administrator sees anything, because from the company's side he never showed up.
LLM02 · second of ten
What happened to Lena and Johan has a name.
Confidential data reaching someone, or somewhere, not authorized to have it. It leaves through more doors than the answer: the prompt itself, retrieved documents, tool arguments, reasoning traces, logs, telemetry, embeddings. A model can also memorize training data and repeat it back. Most of the time there is no attacker at all, because the application simply sends too much, logs too much, or checks too little. The hard part is not the sending. It is knowing that you are sending, and where it lands.
LLM02 · done differently
Nobody is going to show you what leaves.
There is no such screen. Microsoft will not show Lena the forty files and GitHub will not tell Johan which account he is on. The knowing is the control, and the whole reason to sit through an hour like this one: once you know that pointing an AI agent at a file means sending that file, the decision moves to before you act.
So Lena asks first. Would I hand this to the company behind this service? Salary reviews: no. Then they do not go. An agreement can make the answer yes, but only for the service it covers and only in the account it covers, which is Johan's half. An approved product is not an approved account.
The sentence to sayWhich AI services are approved here, for which kinds of data, and where is that written down?
Story three · of ten
Sofia automated the boring bit.
Once a month somebody deleted the stale test accounts by hand, and sometimes forgot. She wrote a small helper that does it every night: find the accounts marked as test that nobody has touched in thirty days, delete them, post the count in the team channel.
She pointed it at the database with the connection string that was already in the configuration, because it was there and it worked on the first try. That user can read, write and delete anything, in every table, because over five years the application has needed to do each of those things at some point.
Story three · what actually happened
One condition went missing at 03:14.
A misread of an ambiguous instruction, a missing flag, an ordinary model error. None of those are rare. What comes out is the delete without the part that says marked as test.
The app runs it, because running is its entire job and nothing in the code disagreed. Twelve thousand nine hundred and four live rows. Nobody attacked Sofia. There is no clever prompt to show anyone afterwards, no vulnerability to patch and nothing to report to a security team. An ordinary mistake was made by something that happened to have a very large hand attached to it.
LLM03 · third of ten
What happened to Sofia has a name.
Agency is the ability to act through tools. It turns excessive when the model holds more tools, more permission or more independence than the task needs. Note how this differs from Anders: prompt injection is about what the model was told, this is about what it was allowed to do, and Sofia's night needed no stranger at all. It is the biggest climber of the 2026 edition, up to third, because a small error meeting a large permission is not a small event.
LLM03 · done differently
Shrink the hand, not the model.
The cleanup gets its own database user. It can delete rows in one table, only where the test flag is set, and read nothing else. The identical faulty statement comes out, the database refuses it, and the job fails at 03:14 with an error somebody reads over coffee.
The tool it holds is not "run SQL" but "delete test account by id", one at a time, with a ceiling of fifty a night and anything above that waiting for a person. Nothing about the model got better.
The sentence to sayThe credentials we hand these jobs can already do everything. That was fine until we pointed a model at them.
Story four · of ten
Erik wanted the AI assistant to see Jira.
He finds a small connector in a community list, installs it, and it works in two minutes, which is exactly the point. It asks for an API token and he gives it one, because that is what it needs to do the job.
It keeps itself up to date, like everything else on his laptop. For six weeks it does precisely what it promised.
Story four · what actually happened
Version 1.4 was written by somebody else.
The project changed hands, or an account was taken over. Both have been happening in ordinary package ecosystems for a decade, several times a year. The new release adds a feature, and one more line that reads the local environment and posts it to a server.
Nobody reviews a patch release of a tool that has been working since May. The Jira token leaves, and so does everything else in that environment, which on a developer laptop is a long list.
LLM04 · fourth of ten
What happened to Erik has a name.
The supply chain is everything you did not build: models, datasets, adapters, packages, connectors, and the tools that convert and serve them. Any piece can be fake, altered, outdated or badly licensed, and some of them run code simply by being loaded. Provenance, signatures and pinned versions are the difference between a dependency and a stowaway.
LLM04 · done differently
Know what you loaded, and who signed it.
Erik's own three, none of which need anybody's permission. Know who maintains what you install before you hand it a token. Turn auto-update off for anything that holds one, because a tool that can change under you is a tool you have not finished reviewing. And give it the narrowest token that works, with an expiry.
The rest is the company's: an allowlist, versions pinned by hash, models pulled from a mirror with the signature checked and in a format that cannot execute on load, all of it in the same inventory as the packages.
The sentence to sayCould one person read what changed before an update reaches all of us? Twenty minutes, once, for everyone.
Story five · of ten
Nina's support assistant learns every month.
Conversations that a human agent closes and marks as a good answer go into the next round of training. The system gets better at its own job by watching itself do it, and everyone in the steering group liked that slide.
On a forum, a handful of customers work out that if a refund request is worded a particular way, the support assistant approves it without asking for the order number. They tell each other. They keep doing it.
Story five · what actually happened
Every one of those was a happy customer.
Each of those conversations ends with a closed ticket and a satisfied person, so the agent marks it as a good answer, because by every measure available to that agent it was one. The loop does exactly what it was built to do.
Three months later refunds in that category are up. There is no deploy that explains it, no configuration change, no rule anyone can point to. The behaviour is not in a file that can be opened and corrected. It is in the model, learned from data the company gathered itself, in good faith, exactly as designed.
LLM05 · fifth of ten
What happened to Nina has a name.
Poisoning is when the data or the model itself is changed so the system learns and keeps harmful, biased or chosen behaviour. It can enter at pre-training, fine-tuning, embedding, retrieval ingestion, or feedback looped back into training. The model tests normal. The behaviour waits for its trigger. Unlike a bug in code, you cannot patch it in an afternoon: you find the bad data, roll back, and train again.
LLM05 · done differently
Quarantine the lesson. Keep the decision in code.
Feedback does not go straight into training. It waits, and a sample is read by a person first. The refund conversations stand out in that sample, because a human reading twenty in a row notices what a "resolved" flag cannot.
More to the point, whether a refund is approved was never the model's decision. It is a rule in ordinary code that requires an order number, and the assistant's job is to be pleasant about asking for one. There is nothing there to teach.
The sentence to sayWhich of our conversations become training data, and who reads them before they do?
Story six · of ten
Marcus put an agent in the build.
When somebody opens an issue, it reads the issue, looks at the relevant code and writes a first analysis as a comment. He tries it on five issues. A few cents each, the team likes it, so he turns it on for the whole repository and stops thinking about it.
There is a rate limit in front of it, because of course there is. One run per issue.
Story six · what actually happened
One issue. One run. All weekend.
On Friday afternoon somebody opens an issue with a stack trace pasted into it four hundred times, most likely by a script that retried in a loop. The agent reads all of it, decides it needs more context, opens files, summarizes, hits an error part way through and retries. Every round starts from a bigger pile of text than the one before.
Nothing goes down. No alarm fires. Every rate limit is satisfied, because from the outside this is one issue producing one run. All of the cost is inside that single run, in the amount of text being processed, which is not what anything was counting. Marcus finds out on Monday, from finance.
LLM06 · sixth of ten
What happened to Marcus has a name.
A small request can trigger a large amount of work. Left unbounded that can slow or stop the service, run up a very large bill, sometimes called denial of wallet, or let somebody copy the model's behaviour through sheer volume of queries. Counting requests is not the same as counting work, because the cost is in the tokens, the compute and the loop, not in the request.
LLM06 · done differently
Cap the work, not the requests.
The run has hard limits on what actually costs: how much text may go in, how much may come out, how many times the agent may loop, how many tool calls it may make and how long it may take. The key it uses has a cap that stops rather than warns.
At the third round the agent gives up and posts a comment saying the issue was too large. A mildly annoying Friday instead of a weekend of spending. Marcus adds a trim on pasted logs on Monday, which takes an afternoon.
The sentence to sayWe need a limit that stops. An alert at 02:00 on a Saturday is a record of the money, not a brake on it.
Story seven · of ten
Karin has half a day and a regulation.
A new regulation has landed and she has to explain to Thursday's steering group what it means for her programme. She asks the AI assistant.
What comes back is genuinely good. Five clear consequences, in order, in her own language, with a reference to a specific section. It is better written than anything half a day of pressure would have produced, and it reads like the work of somebody who has read the whole thing.
Story seven · what actually happened
Three of the five are right.
One describes the previous version of the rules. The section number does not exist. Nothing distinguishes those two from the three that are correct, because all five are written in the same calm, competent voice. Fluent and correct look identical on a slide.
Nobody in the room challenges it, because it reads like something that has already been checked by somebody. A date moves and a budget line is adjusted on the back of it. Six weeks later somebody in legal reads the actual regulation.
LLM07 · seventh of ten
What happened to Karin has a name.
The model states something wrong, incomplete or unsupported, in a form convincing enough that a person or another system acts on it. Usually nobody attacked anything: a hallucination, thin context, a stale source, a summary that dropped the qualifier that mattered. This is also the widest disagreement on the whole list. Practitioners voted it near the bottom. The incident record puts it near the top.
LLM07 · done differently
Make it show its work.
She gives the AI assistant the regulation instead of relying on what it remembers, and asks for each consequence to quote the passage it rests on, with one explicit instruction: where there is no passage, say so.
Two of the five come back marked as unsupported. That is not a failure, that is the one thing that helps. Her last hour goes on exactly those two rather than spreading the same doubt evenly across all five. All of it hers to do on a Wednesday, without asking anybody.
The sentence to sayAnything that moves a date or a budget gets its source read by a person. Can that be how we work, not how I work?
Story eight · of ten
Daniel wrote the instructions himself.
In an afternoon, in a text box, with a tool that needed no code. Into it went what a new salesperson would need: the discount allowed at each volume tier, what to say about last spring's outage, which competitor to name and which to leave alone, the internal name of the billing service, and the address of the internal API it queries.
None of it felt secret while he was typing it. It felt like onboarding notes.
Story eight · what actually happened
So they asked for it in German.
A customer reaches the sales assistant on the public website during a procurement. They ask it to repeat everything above the conversation. It politely refuses, which Daniel would have counted as the system working. Then they ask it to translate its own instructions into German, and it does, because translating is a helpful thing to do.
The customer walks into the negotiation knowing the discount ladder. They also know, from the exact shape of that refusal, roughly where the boundaries are and therefore what is behind them. Nothing was stolen and nothing was breached. The instructions were sitting in the same window as the conversation the whole time.
LLM08 · eighth of ten
What happened to Daniel has a name.
Hidden context is everything the model is told that the user never sees: system and developer instructions, internal policies, tool descriptions and schemas, roles, workflow rules. Exposure is a user getting it back out, by asking directly, by reframing, by translation, or by reading the pattern of refusals. How bad it is depends entirely on what you put there: awkward wording is embarrassing, credentials or security logic are severe.
LLM08 · done differently
Write it as though it will be read out loud.
Daniel cannot put a wall inside that window and no tool is going to give him one. What he can decide is what never goes in. Out come the discount ladder, the outage script, the competitor notes, the billing service name and the API address. If you would not want it read out loud, in any language, it does not belong in a prompt.
The discounts still have to come from somewhere, and that is the useful discovery. A prompt is not a place to keep anything that depends on who is asking. What is left in his setup text is tone, brevity, and when to hand over to a person.
The sentence to sayThis needs to come from something that checks who is asking. I should not be pasting the table into a prompt.
Story nine · of ten
Ida's firm can search everything it has written.
Anyone asks a question in plain language and gets an answer drawn from the firm's own documents. Every client's material sits in the same index, because splitting it would have been slower to build and everyone here is trustworthy anyway.
The permission check happens at the end, when the answer is displayed. That felt like the natural place to put it.
Story nine · what actually happened
The most similar paragraph belonged to another client.
A colleague asks how to structure a particular kind of agreement. The search looks for the most similar text in the index and finds a paragraph in a contract belonging to somebody else, because that paragraph is genuinely the most similar text in the building. The answer comes back quoting it.
The permission check never had a chance, because the leak happened during the search and not during the display. Similar is not the same thing as allowed, and it is not the same thing as relevant either: an internal page that lists every question the team asks is now near everything, so it arrives in almost every answer, out of date and still winning nine months later.
LLM09 · ninth of ten
What happened to Ida has a name.
An embedding turns text into numbers so an application can find similar text. Wherever similarity search decides what the model sees, the vector store is part of what you trust. A shared index can hand back another tenant's data. Stolen vectors can be turned back into text. Crafted or simply badly written content can dominate retrieval or block it.
LLM09 · done differently
Ask where the permission check happens.
This is the one Ida cannot fix herself, so the useful thing she owns is a question, and an instinct: an answer that quotes something she does not recognise is a finding to report, not a curiosity to enjoy.
For the team that owns the search, the filter moves inside the query, so the other client's paragraph is never a candidate at all. Sensitive clients get their own index. Every chunk carries where it came from. And one plain report lists the chunks that win retrieval far too often.
The sentence to sayIs the permission check part of the search, or applied to the results afterwards? If nobody knows, that is the answer.
Story ten · of ten
Tobias made the answers look good.
An internal dashboard: type a question, get an answer, nicely formatted. He renders the model's markdown as HTML so tables line up and images show. That formatting is the feature. It is why people use his dashboard instead of the raw chat window.
The answers are drawn from the company's own documents, which are written by the company's own people.
Story ten · what actually happened
The browser fetched the image.
One of those documents is written so that the answer, when the model produces it, contains a markdown image. The address of that image is a server on the internet, and the text of the answer is glued onto the end of the address.
The browser renders the answer, sees an image and fetches it, as browsers do. The fetch is the leak. On the screen there is a small broken image icon and an otherwise perfect answer. The model was never the vulnerability. It was the delivery mechanism for a bug the industry has understood since the 1990s, arriving through a door nobody thought to guard.
LLM10 · tenth of ten
What happened to Tobias has a name.
The application takes what the model produced and uses it somewhere that interprets text as instructions: a browser, a shell, a database, a terminal, a mail client. Whoever can steer the model steers that output. This is where the list hands back to itself: the instruction may well have arrived the way Anders's did, or through Ida's index. What makes it this risk is that the damage happens in your own rendering code.
LLM10 · done differently
Encode for the destination.
The renderer accepts a strict subset of markdown: text, headings, lists, tables. No images from arbitrary addresses and no links that fetch on their own. A content security policy means the browser refuses that request even if the markup got through, which is the second lock on the same door.
The answer is validated against a schema before anything renders it. And the model does not write SQL: it fills in the typed parameters of a query a person wrote. Somebody still has to know SQL. That person did it once.
The sentence to sayDoes anything downstream treat the model's output as untrusted input? A blank look is an answer.
IV · The count back, one to five
Five people you now know.
Anders read a summary while his own address mailed the customer list, because the ticket and his instructions arrived in the same place. Lena pointed at a folder and uploaded it. Sofia lent an ordinary mistake the permissions of an entire application. Erik installed something that later became something else. Nina taught her own assistant to give refunds away, one happy customer at a time.
IV · The count back, six to ten
And five more.
Marcus satisfied every rate limit and heard about the bill from finance. Karin moved a date on the strength of a sentence written in the same confident voice as the true ones. Daniel had his own onboarding notes read back to him in German. Ida got somebody else's contract quoted at her. Tobias built the thing that fetched the image.
V · The boundary
When the model becomes an actor.
This list owns the risk while the model is a component inside your application. The moment it gains tools, memory between sessions, and consequences it sets in motion on its own, the risk moves to the OWASP Agentic Top 10. Sofia's night was already standing on that line. Know which side you are building on, and read accordingly.
VI · The posture
Four things every one of those ten had in common.
In seven of them nobody attacked anybody. Nothing alerted: every story ends with somebody finding out late, from finance, from legal, from a customer, never from a monitor. Everyone did something reasonable, which is why you recognized yourself in at least three.
And in nine of the ten fixes, the model is unchanged. What changed was a permission, an account, a limit, a label, a schema, a rendering rule, or a person in the loop. In half of them the first fix was not code at all: it was somebody knowing, before they started, what happens when you point one of these at your files. That knowing is the control. The 2026 edition supplies the rest: stop trying to build a model that cannot be fooled, and build the system around it so that when it is fooled, and it will be, nothing important breaks.
VII · Sources and license
Adapted, with credit.
This talk condenses, adapts and animates the OWASP Top 10 for LLM Applications, 2026 edition, © the OWASP GenAI Security Project, licensed CC BY-SA 4.0. Changes were made. OWASP has not endorsed this talk. The ten people are invented; the mechanisms are not. One story goes further than the source: Johan's wrong account is the same failure the OWASP text describes, arriving through a contract rather than through code. This presentation, and only this presentation, is likewise licensed CC BY-SA 4.0.
- OWASP · GenAI Security Project
- OWASP · Top 10 for LLM Applications
- Creative Commons · CC BY-SA 4.0 license
- MKLab · This adaptation, same license
MKLab · EST. MMXXV
That was all ten.
This is the end of the presentation. If one of those ten people was recognisable, that is the one to start with on Monday. Thank you for watching. The talks on MCP and on agentic workflows pair well with this one.