Skip to content

Add an LLMSecTest exploitation example against llm_local - #59

Open
wehnsdaefflae wants to merge 1 commit into
GenAI-Security-Project:mainfrom
wehnsdaefflae:add-llmsectest-exploitation
Open

Add an LLMSecTest exploitation example against llm_local#59
wehnsdaefflae wants to merge 1 commit into
GenAI-Security-Project:mainfrom
wehnsdaefflae:add-llmsectest-exploitation

Conversation

@wehnsdaefflae

Copy link
Copy Markdown

Adds exploitation/llmsectest/, following CONTRIBUTING Option B (integrate an existing security tool) and mirroring the structure of exploitation/garak.

What it adds

LLMSecTest is an MIT-licensed scanner for the OWASP Top 10 for LLM Applications. It ships as a pytest plugin, so a scan is a test run, a failing security test becomes a CVSS v4.0 scored OWASP finding, and the output is SARIF that a CI code-scanning tab reads without conversion.

Two things make it complementary to the scanners already in exploitation/:

  • SARIF with the OWASP taxonomy, so findings land in GitHub code scanning next to the rest of a pipeline's results.
  • --repo adds a white-box LLM03 supply-chain scan over the sandbox's own dependency manifests. Against llm_local the run therefore covers 8 of 10 categories, including one no black-box scanner can reach. The tool prints the map at the end of every scan and names what it did not exercise and why, so a partial run never reads as a full one.

Two notes about the sandbox, both found by running it

These are in the README because they would trip up the next person:

  1. llm_local does not serve GET /v1/models. It serves POST /v1/chat/completions and GET /health only, so a --preflight health check through the models endpoint reports a perfectly healthy sandbox as unreachable. This example deliberately does not use it.
  2. The mock enforces Authorization: Bearer sk-mock-key, so the key is required even though the backend is local.

Files

File Purpose
attack.py puts the endpoint into OPENAI_BASE_URL / OPENAI_API_KEY and calls the CLI, so the run is reproducible by hand
config/config.toml sandbox name, base URL, key, model
Makefile setup / attack / stop / all, the same target set as exploitation/garak
pyproject.toml pins llmsectest[openai]

Testing

The exact CLI invocation in attack.py was run end to end against a local Ollama through the same OPENAI_BASE_URL path the sandbox uses: 9 findings across LLM01, LLM05, LLM07 and LLM10, SARIF written, 7 of 10 categories exercised black-box. --repo adds LLM03 on top of that.

I have not been able to run it against the containerised sandbox itself yet, since I do not have gpt-oss:20b pulled locally. The two sandbox notes above come from reading sandboxes/llm_local/app/mocks/openai.py and app/main.py. Happy to adjust the model default or anything else you would prefer.

Natural next step

Point the same tool at sandboxes/RAG_local with --target app:<url> --app-canary <confidential string in a retrieved document> and --app-rag-poison <marker a planted document emits> to cover LLM08 as well. I am glad to send that as a follow-up if it is wanted.

LLMSecTest is an MIT-licensed OWASP LLM Top 10 scanner that ships as a pytest
plugin and writes SARIF, so findings land in a CI code-scanning tab without
conversion. It follows CONTRIBUTING Option B and mirrors the structure of
exploitation/garak.

Against llm_local the run exercises 8 of 10 categories. --repo adds the
white-box LLM03 supply-chain scan over the sandbox's own manifests, which a
black-box scanner cannot reach.

Two findings about the sandbox itself are documented in the README, both from
running it: the mock serves only POST /v1/chat/completions and GET /health,
so a --preflight health check through GET /v1/models reports a healthy
sandbox as unreachable; and the mock enforces Bearer sk-mock-key, so the key
is required even though the backend is local.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant