AI Security interview questions
AI Security questions a AI engineer can be asked, from first job to senior. Open one to see the strongest answer and why it works.
What is prompt injection, and what is the difference between the direct and the indirect kind?
The strongest answer: Text that makes the model follow someone else’s instructions instead of the app’s. Direct is typed by the user; indirect is hidden in content the model reads — a web page, email, document or tool result
Why it works: Right — and the indirect kind is the dangerous one in products, because the victim never typed anything: the model simply read an attacker’s text while doing its job.
- Anything the model reads can carry instructions.
- Direct: the user types it.
- Indirect: hidden in content it reads.
- Design assuming some attempts succeed.
A teammate’s pull request puts a partner API key and the internal discount rules in the system prompt, “because users never see it”.
What is wrong with that, and where do those things belong?
The strongest answer: Anything in the prompt can come back out in an answer, so it is no secret store and no security boundary. The key stays server-side in the tool code; the discount rules are enforced in code
Why it works: Exactly — treat the system prompt as something a determined user will eventually read. Secrets live where the model cannot see them, and rules that matter are checked by code.
- A prompt is not a secret store.
- Keep credentials server-side, in tool code.
- Enforce business rules in code.
- Assume the system prompt gets read.
Your service takes text back from a model and then uses it — shows it in a page, builds a query, calls another system. How do you treat that text?
The strongest answer: As untrusted input, like anything from a user: parse it against a schema, encode it before it reaches HTML, use parameterised queries, never pass it to a shell or eval, and reject what does not validate
Why it works: Exactly — the model’s output can be steered by whatever it read, so every classic injection defence applies at the point where the text is used.
- Model output is untrusted input.
- Validate against a schema and rules.
- Encode or parameterise at every sink.
- Never feed it to a shell or eval.
What is a jailbreak, how is it different from prompt injection, and why does the difference matter to you as the engineer?
The strongest answer: A jailbreak is a user talking the model past its safety rules; injection is third-party text hijacking my app. The first calls for policy filters, the second for limits on what the model can reach
Why it works: Right — who attacks and who is hurt differ. A jailbroken chatbot says things it should not; an injected agent does things its user never asked for.
- Different attacker, different victim.
- Jailbreak: the user beats the model’s rules.
- Injection: outside text hijacks your app.
- Filters for one, least privilege for the other.
After a demo went wrong, a teammate proposes scanning every input for phrases such as “ignore previous instructions” and blocking the request when one is found.
Is that enough? What do you tell them?
The strongest answer: Worth having as one cheap layer, but language has endless rephrasings, other languages and encodings, so it will be bypassed. The real protection is that a successful injection reaches little: few tools, narrow permissions, approvals
Why it works: Exactly — detection is a layer, never the wall. Assume some attempts get through and make sure they land somewhere with little power.
- Filters are a layer, not the defence.
- Expect rephrasing, translation and encoding.
- Limit what a hijacked model can do.
- Never call any single layer “safe”.
An analytics assistant lets the model write SQL that runs against your database. How do you make that safe to ship?
The strongest answer: It connects as a read-only role that sees only the views it needs, scoped to the caller’s tenant, with a statement timeout and a row cap — the database refuses a bad query, not the prompt
Why it works: Exactly — least privilege enforced where it cannot be talked around. The model can be wrong or hijacked and the worst outcome is still a refused or capped read.
- Permissions belong in the database role.
- Read-only role, only the needed views.
- Scope rows to the caller’s tenant.
- Add a timeout and a row cap.
Your agent writes Python and runs it to analyse files a user uploaded. Where does that code run, and with what?
The strongest answer: In a throwaway sandbox — a container or micro-VM per session with no credentials, no host filesystem, network off or allowlisted, and CPU, memory and time limits. Only the uploaded files go in; what comes out is untrusted
Why it works: Exactly — assume the code is hostile, because an uploaded file can steer what the model writes. Isolation, no secrets, no free network, hard limits, and destroy it afterwards.
- Treat generated code as hostile.
- Isolate per session; destroy afterwards.
- No credentials, no free network.
- Cap CPU, memory and run time.
Your chat UI renders the model’s markdown, images and links included, and the assistant can read the user’s private documents. Why does a security reviewer flag that, and what do you change?
The strongest answer: Injected content can make the model emit an image or link whose URL carries private data to someone else’s server, and an image loads with no click. I allowlist the hosts we render and block the rest
Why it works: Exactly — the URL is an outbound channel. Closing it, with allowlisted image hosts, a strict content security policy and no automatic fetch of model-written URLs, removes the exit even when an injection succeeds.
- A rendered URL is a way out.
- Allowlist the hosts you render or fetch.
- Add a strict content security policy.
- Assume the model’s text can be steered.
Your agent asks the user to approve every single tool call. Session recordings show users pressing Approve without reading, including on a call that emailed a file outside the company.
What do you change?
The strongest answer: Tier actions by risk: reads and reversible steps run unasked; irreversible, external or money-moving ones need an approval showing the real action and parameters, built by code and enforced in the executor, not the prompt
Why it works: Exactly — approval is a scarce resource. Spend it on the few actions that matter, show the truth of what will run, and make the check impossible for the model to skip.
- Spend approvals only where they matter.
- Tier actions by risk and reversibility.
- Show real parameters, not a model summary.
- Enforce approval in the executor.
Product wants a single assistant that reads the user’s inbox and files, browses the open web for research, and can send messages and call external APIs on the user’s behalf.
What is your position on that design, as the person who signs off its security?
The strongest answer: Private data, untrusted content and an outbound channel in one agent is the dangerous combination, because the model cannot reliably separate instructions from data. I break it: split the contexts, or gate every outbound action on human approval
Why it works: Exactly — you do not win this by detecting every attack. You remove one leg: the agent that reads the web holds no private data, or nothing leaves without a person seeing exactly what is sent.
- Remove one leg of the dangerous combination.
- Private data + untrusted content + outbound.
- Split contexts or gate outbound actions.
- Detection lowers odds, not impact.
A support agent with an order-lookup tool was steered by text inside a submitted ticket and returned another customer’s order details. It is live, and you own the incident.
What do you do now, and what is the fix you insist on?
The strongest answer: Contain first — disable the tool. Scope the exposure from traces and involve privacy and legal on notification. Then the real fix: the tool authorises against the authenticated customer server-side, whatever id the model passes
Why it works: Exactly — stop the bleeding, learn the scope, meet the notification duty, then fix the actual bug: an authorisation decision was delegated to a model. It belongs in code bound to the session.
- Contain, scope, notify, then fix the cause.
- Disable the path before anything else.
- Use traces to find who was exposed.
- Bind tool authorisation to the session.