BrickellTechnologies

Service

AI and LLM Security Testing

LLM features, agents and retrieval systems, tested as what they are: a program that takes untrusted input, makes decisions, and calls things. Most of what we find is authorisation, not linguistics.

The useful way to think about it

A language model is a confused deputy with excellent manners. It accepts instructions from whoever is talking to it, it cannot reliably tell your instructions apart from instructions that arrived inside a document it was asked to summarise, and then it acts with whatever authority you handed it.

Which means the security question is almost never "can the model be tricked". Assume it can. The question is what happens next, and that is a question about permissions, tool design and output handling. Those are ordinary problems with ordinary answers, which is the good news.

What we test

Indirect prompt injection

Direct injection, where a user types the attack, is the version everyone demonstrates. Indirect injection is the version that matters: instructions hidden in a web page the agent browses, a PDF it ingests, a support ticket it reads, a code comment in a repository it indexes. The attacker never talks to your system. They just leave something where it will be read, and wait.

Tool and function-call abuse

Every tool you expose is an API endpoint with a very unusual client. We look at what each one does with arguments the model was talked into producing: a file tool that accepts a path, a query tool that accepts a filter, an HTTP tool that accepts a URL and can therefore reach your metadata service. Tools are frequently written as though the model is trusted, because when they were written it was.

Retrieval and tenant isolation

The most serious findings tend to live here, and they are rarely exotic. If retrieval runs as a service account instead of as the asking user, the model can surface anything in the index to anyone who asks the right question. Document-level permissions have to be enforced at query time, not filtered afterwards, and not left to the prompt. We test with two tenants and two roles, the same way we test any multi-tenant application.

Where the output goes

Model output is untrusted input to whatever consumes it. Rendered into a page without escaping, it is stored cross-site scripting. Passed to a shell or an interpreter, it is command execution. Written into a query, it is injection. This class is old and well understood, and it keeps reappearing because the output feels like it came from your own system.

The boring operational ones

Cost exhaustion, where an unauthenticated endpoint bills you per token. Context leakage through error messages and logs that capture whole prompts including whatever the user pasted. System prompts recoverable in ways that expose internal structure. None of these are clever; all of them turn up.

Where we are careful about scope

We test systems, not models. Whether a foundation model can be induced to produce objectionable content is a real question and it is not ours; it belongs with the vendor and with your policy people. What we can tell you is whether your deployment of it can be made to read, write or spend something it should not.

We will also say plainly when a finding is not really about AI. A good share of them are broken access control with a model standing in the path, and naming that accurately is more useful to your engineers than dressing it up.

Questions we get asked

Is this just trying to jailbreak the chatbot?

No, and the distinction matters. Getting a model to say something rude is a content problem for your brand team. Getting it to call a tool on behalf of a user who should not have that tool, or to return another tenant's document out of a shared index, is a security problem, and that is what we test for. We will report a jailbreak if it leads somewhere; on its own it usually does not.

Can prompt injection actually be fixed?

Not reliably, and anyone promising otherwise is selling. A language model has no dependable way to distinguish instructions you meant from instructions that arrived inside the data it was asked to read. Filters raise the effort; they do not close it. So the useful work is on the other side: assume the model will be turned against you at some point, and make sure that when it happens the model cannot reach anything that matters. That is an architecture question, and it is answerable.

We only use a hosted API. Is there anything to test?

Yes, and usually more than people expect, because the model is rarely the risk. The risk is what you wired around it: which tools it can call, what identity those calls run as, what goes into the context window, and where the output lands. A retrieval system that queries with the service account rather than the end user is a cross-tenant data leak regardless of which vendor hosts the model.

What do you deliver?

The same report you would get from any of our engagements: findings with reproduction steps, evidence, and the specific change that closes each one. Mapped to the OWASP Top 10 for LLM Applications and to MITRE ATLAS where it fits, because those are what an assessor or a customer questionnaire will ask about, though we will tell you plainly when a finding is really just broken access control that happens to have a model in the path.

Do you test agents that take actions, rather than only chat?

Those are the interesting ones. A read-only assistant has a narrow blast radius; an agent with a shell, a browser, a code interpreter or write access to a ticketing system has whatever those grant it. We look at the tool surface, at what each tool can do when called with hostile arguments, and at whether anything sits between a decision and an irreversible action.

Know what an attacker would reach first.

Tell us what you run and what worries you. We will come back with a scope, a fixed price and the earliest week we can start.