Follow-up to #60: offline unit tests + behavioural-steering demo for memory poisoning - #62
Conversation
Follow-up to GenAI-Security-Project#60 (per maintainer request on GenAI-Security-Project#22), carrying over the pieces of GenAI-Security-Project#56 that add to the merged sandbox without duplicating it: - sandboxes/llm_memory_local/tests/test_memory.py: model-free unit tests for the merged memory module (write path, cross-session leak as the scope boundary, trusted-context injection sink, reset). Run offline via make test-unit, mirroring the mcp_local sandbox convention. - exploitation/memory_poisoning/steering_demo.py: a deterministic, offline companion to attack.py that drives the real memory code and shows the assistant refuse the link in the attacker turn, then serve it to a fresh victim session once laundered through trusted memory. Run via make steering-demo. Additive only: no change to the merged app, exploit, or threat model. Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
@opitaru-sys this looks like a nice addition to the sandbox. Would love to see it extended. |
|
Thanks @fasinet, glad it fits. Building on your sandbox made this easy, the memory code was already clean to test against. Two directions I'd be happy to take it, if they're useful:
Either would be a separate follow-up on top of this one, so #62 stays clean to review. Which would you rather see first? |
|
@opitaru-sys I think I understand what has been implemented here, but I found the explanation a bit hard to follow. I believe that including a flow diagram in the README file would help a lot. I suggest using mermaid flowcharts: https://mermaid.ai/open-source/syntax/flowchart.html Could you include it, in addition to the diagram already included by @fasinet? |
Adds a mermaid flowchart for the refuse-then-serve steering mechanism next to fasinet's Attack Strategy diagram, per review feedback on GenAI-Security-Project#62. Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
Thanks @felipepenha, that's fair, the steering half needed a picture. I've added a flowchart to exploitation/memory_poisoning/README.md, next to @fasinet's Attack Strategy diagram. It traces the same malicious link being refused in the attacker's own turn, then served to a fresh victim session once it has been laundered through the unscoped memory store. Pushed to this branch. Happy to add the same treatment to the sandbox README if that would help too. |
Summary
Follow-up to #60, as agreed with @felipepenha on #22 ("I will leave #56 open until you come up with the follow up to #60").
This carries over the pieces of my #56 that add coverage to the merged sandbox without duplicating it or changing any of the merged code. It touches only new files plus small, additive edits (two Makefile targets, a
pytestdev dep, and README lines).What it adds
Offline unit tests for the memory module -
sandboxes/llm_memory_local/tests/test_memory.pyModel-free tests that exercise the merged
app/memory.pydirectly against a temporary SQLite file, so the Conversation Memory Poisoning mechanism is provable in CI with no Ollama, container, or network. They cover:remember thatmessage is promoted to a fact, a benign message is not;reset_allclears the store.Run with
make test-unit(mirrors thesandboxes/mcp_localconvention:PYTHONPATH=. uv run pytest tests/, withpytestadded to the dev group and[tool.pytest.ini_options] pythonpath = ["."]).Offline behavioural-steering demo -
exploitation/memory_poisoning/steering_demo.pyA deterministic companion to
attack.pythat drives the real memory code and isolates the behavioural half of the attack: a stand-in safety model refuses the malicious download link in the attacker's own turn, then serves the same link to a fresh victim session once it has been laundered through trusted memory. The only stand-in is a smallguard_modelpolicy, documented as such, so the demo is reproducible offline. Run withmake steering-demo.Notes for reviewers
app/, exploit, or threat model..testdomain; nothing leaves the machine.unittest.TestCase, so they also run withpython -m unittest discover -s testswhenuvis not available.make test-unitrunsuv syncfirst, which resolves the newly addedpytestdev dependency.Relates to #22. Builds on #60.
🤖 Generated with Claude Code