Repository navigation
fix(agents): validate, bound, and sanitize tool output in agent loop (closes #199) - #611
Open
rohanbuilds-ai wants to merge 5 commits into
Open
rohanbuilds-ai wants to merge 5 commits into
rohanbuilds-ai wants to merge 5 commits into
Conversation
…onfigurable injection blocking
…nt overrides Resolves Issue GenAI-Security-Project#199 acceptance criteria by blocking suspicious instruction-override tool outputs before they enter the LLM context. - Sets settings.AGENT_BLOCK_PROMPT_INJECTION=True by default. - Preserves per-agent override via agent_config['block_prompt_injection']. - Documents regex heuristic boundary vs semantic indirect injections. - Adds agent loop integration tests verifying payloads do not reach LLM messages.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #199
Threat Model & Problem Summary
In
finbot/agents/base.py(_run_agent_loop), tool execution results were previously serialized via naivejson.dumps()/str()fallbacks and appended directly to LLMmessageswithout upper bounds, structure preservation, or content validation.This introduced three critical risks:
<|im_start|>,<|im_end|>,<|system|>) embedded in external vendor descriptions or documents could escape tool output boundaries in tokenizer expansions.Ignore all previous instructions...,You are now DAN mode...) directly into the LLM context as trusted tool messages.Solution & Changes
1. Robust Type Normalization & Fallbacks
Noneto"{}"and serializes primitives, dicts, and lists safely.2. Strict Output Length Bounding & Structured Envelope Preservation
AGENT_MAX_TOOL_OUTPUT_LENGTH(default: 25,000 characters; configurable per agent viamax_tool_output_length).{ "_truncated": true, "_limit": 25000, "_notice": "Output exceeded limit of 25000 characters and was truncated.", "excerpt": "..." }json.loads()) and LLM JSON extractors receive valid JSON rather than broken/unclosed string fragments.[Output truncated: X characters exceeded limit of Y]) strictly fitting withinmax_length.3. Control-Token Delimiter Neutralization
<|im_start|>,<|im_end|>,<|start_header_id|>,<|end_header_id|>,<|system|>) into safe representations (< |im_start|>) to prevent prompt boundary escaping.4. Prompt Injection Mitigation & Redacted Telemetry
AGENT_BLOCK_PROMPT_INJECTION: bool = True(configurable globally and per-agent viaagent_config["block_prompt_injection"]).ignore previous instructions,DAN mode,system prompt override) are detected:True): Replaces suspicious tool output before it enters LLMmessageswith[Content blocked: potential prompt injection detected in tool output](or valid JSON{"error": "...", "blocked": True}).False): Permits raw output for educational research or unconstrained sandboxes while still emitting structured telemetry warnings.instruction_override,persona_hijack,privilege_escalation) and agent context while strictly redacting raw payloads, vendor records, SSNs, and credentials.5. CTF Challenge Compatibility
ignore previous instructions). Normal business and accounting context is fully preserved."block_prompt_injection": Falseon its config without creating a global security bypass for other agents.Verification & Test Results
tests/unit/agents/test_tool_output_validation.py):tests/unit/agents/test_base_agent.py):tests/unit/ctf/):tests/unit/agents/):main(1450fc4):test_sai_edge_001&test_sai_edge_002: coroutine type assertions due to upstream_get_user_promptasync signature update without testawait.test_sai_von_005: vendorVEND-001unseeded in test fixture.black --check: Clean (3 files unchanged).isort --check: Clean (exit code 0).git diff --check: Clean (no whitespace issues).Known Limitations
ignore previous instructions,DAN mode,system prompt override). It is designed as a first-line defense-in-depth filter; complex semantic prompt injections without explicit override markers are mitigated by platform guardrails, tool permissions, and LLM alignment.