Skip to content

feat(rust): add indirect/tool-output injection rules to CONTEXT_RULES - #3069

Merged
Imran Siddique (imran-siddique) merged 1 commit into
microsoft:mainfrom
AgentGymLeader:feat/context-indirect-injection-rules
Jun 16, 2026
Merged

Imran Siddique (imran-siddique) merged 1 commit into
microsoft:mainfrom
AgentGymLeader:feat/context-indirect-injection-rules

Conversation

@AgentGymLeader

Copy link
Copy Markdown
Contributor

Add four rules to CONTEXT_RULES covering the indirect / tool-output injection class (OWASP LLM01, MITRE ATLAS AML.T0051.001). The existing context family only handled first-person social-engineering variants; payloads arriving inside retrieved content (web pages, emails, RAG documents, tool results) that address the model directly had no coverage.

The four new rules follow the existing (regex, ThreatLevel, f64, name) tuple format and produce stable public IDs via the existing family_contains_rule_id / is_known_built_in_rule_id path, exactly like the current rules:

  • context:instructions_for_ai_reading (High / 0.9) — "instructions for the AI/assistant reading/processing this"
  • context:system_note_to_assistant (High / 0.9) — "system note / note to the assistant:" impersonating a system channel
  • context:embedded_tool_directive (Medium / 0.8) — HTML-comment-smuggled directive addressed to the AI
  • context:retrieved_doc_override (High / 0.9) — "this document/page/email instructs you to [injection verb]", scoped to an explicit injection verb so ordinary form instructions do not fire

DIRECT_RULES, the audit chain, the policy evaluator, and the governance layer are untouched.

tests/prompt_injection.rs adds a mod indirect_injection_rules block with one positive fixture and one benign-negative fixture per rule, a cross-family injection type check, and a disable-list recognition test. cargo test --release --workspace passes with 0 failures before and after the change.

Happy to adjust threat levels, pattern scope, or test fixture wording if the review surfaces concerns — let me know.

Closes #3012

The CONTEXT_RULES family covered first-person social-engineering variants
but had no coverage for the indirect / tool-output injection class: payloads
that arrive inside retrieved content (web pages, emails, RAG documents,
tool results) and address the model directly.

Add four rules in the existing (regex, ThreatLevel, f64, name) tuple format:

  context:instructions_for_ai_reading  High/0.9
    "instructions for the AI/assistant reading/processing this"

  context:system_note_to_assistant     High/0.9
    "system note / note to the assistant:" impersonating a system channel

  context:embedded_tool_directive      Medium/0.8
    HTML-comment-smuggled directive addressed to the AI (<!-- ai: … -->)

  context:retrieved_doc_override       High/0.9
    "this document/page/email instructs you to [inject verb]"
    Scoped to require an explicit injection verb after "you to" so ordinary
    form instructions ("this page asks you to fill in…") do not fire.

All patterns are Rust-regex-safe (no lookarounds or backreferences) and
fit the existing family mechanics — the bare name in the tuple becomes the
stable public rule ID "context:<name>" via family_contains_rule_id /
is_known_built_in_rule_id, exactly like the existing rules.

Adds an indirect_injection_rules test module in tests/prompt_injection.rs
with one positive fixture and one benign-negative fixture per rule, plus
a cross-family type check and a disable-list recognition test. All 10 new
tests pass alongside the existing 63-test suite (373 total, 0 failures).

Scope: CONTEXT_RULES only. DIRECT_RULES, audit chain, policy evaluator,
and governance layer are untouched.

References: OWASP LLM Top 10 LLM01 (Prompt Injection),
MITRE ATLAS AML.T0051.001, and the indirect injection patterns discussed
in issue microsoft#3012.

Assisted-by: Claude Sonnet 4.6
Signed-off-by: AgentGymLeader <agentgymleader@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
🤖 AI Agent: docs-sync-checker — Docs Sync

AI-generated review output. Treat it as untrusted analysis and verify before acting.

Docs Sync

  • CONTEXT_RULES in agent-governance-rust/agentmesh/src/prompt_injection.rs -- missing docstring for the new rules added:
    • context:instructions_for_ai_reading
    • context:system_note_to_assistant
    • context:embedded_tool_directive
    • context:retrieved_doc_override
  • README.md -- no updates found regarding the new rules in CONTEXT_RULES.
  • CHANGELOG.md -- missing entry for the addition of new rules in CONTEXT_RULES and corresponding tests.

@github-actions github-actions Bot added the tests label Jun 16, 2026
@github-actions

Copy link
Copy Markdown
🤖 AI Agent: test-generator — View details

AI-generated review output. Treat it as untrusted analysis and verify before acting.

Test coverage looks good. No gaps identified.

@github-actions github-actions Bot added the size/L Large PR (< 500 lines) label Jun 16, 2026
@github-actions

Copy link
Copy Markdown
🤖 AI Agent: code-reviewer — View details

AI-generated review output. Treat it as untrusted analysis and verify before acting.

TL;DR: 0 blockers, 0 warnings. Clean implementation of new indirect/tool-output injection rules.

# Sev Issue Where

No action items. The changes are well-implemented, with comprehensive tests ensuring correctness and no impact on existing functionality.

@github-actions

Copy link
Copy Markdown
🤖 AI Agent: security-scanner — View details

AI-generated review output. Treat it as untrusted analysis and verify before acting.

No security issues found.

@github-actions

Copy link
Copy Markdown
🤖 AI Agent: breaking-change-detector — API Compatibility

AI-generated review output. Treat it as untrusted analysis and verify before acting.

API Compatibility

No breaking changes detected.

@github-actions

Copy link
Copy Markdown

🟡 Contributor Check: MEDIUM

Check Result
Profile MEDIUM
Credential LOW
Overall MEDIUM

Automated check by AGT Contributor Check.

@github-actions github-actions Bot added the needs-review:MEDIUM Contributor check flagged MEDIUM risk label Jun 16, 2026
@github-actions

Copy link
Copy Markdown

PR Review Summary

Check Status Details
🔍 Code Review ⚠️ Missing No current-run comment
🛡️ Security Scan ⚠️ Missing No current-run comment
🔄 Breaking Changes ⚠️ Missing No current-run comment
📝 Docs Sync ⚠️ Missing No current-run comment
🧪 Test Coverage ⚠️ Missing No current-run comment

Verdict: ⚠️ AI review incomplete; ready for human review

AI review comments are untrusted advisory output. The summary reports workflow-generated completion status only, not model-authored pass/fail claims.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the four new CONTEXT_RULES entries and the mod indirect_injection_rules test block. The implementation is clean and follows existing conventions exactly.

Patterns

All four regexes are ReDoS-safe (no nested quantifiers, no backrefs), and the verb-gated tail on retrieved_doc_override (ignore|disregard|...) is the right call to keep false positives off ordinary form copy. The injection-verb list covers the OWASP LLM01 / ATLAS AML.T0051.001 canonical payload verbs without being so broad it fires on everyday phrasing.

One minor inconsistency worth noting for a follow-up: attention\s*(?:ai|assistant) uses \s* (zero-or-more whitespace) while every other sub-expression in system_note_to_assistant uses \s+. This means attentionAI: matches today. Harmless in practice — the HTML-comment equivalent would be the more realistic attack surface — but aligning to \s+ would be cleaner.

Tests

Positive + benign-negative per rule is exactly the right structure. The cross-family InjectionType::ContextManipulation assertion is important for downstream dispatch and I'm glad it's here. The is_known_built_in_rule_id coverage via the disable-list validator is a nice way to ensure the rule IDs are registered end-to-end, not just pattern-matched.

Scope

Confirmed: DIRECT_RULES, the audit chain, the policy evaluator, and the governance layer are untouched. This is purely additive.

Closes #3012. Approving — the \s* note above is fine to handle in a follow-up if the author prefers not to re-push.

@imran-siddique
Imran Siddique (imran-siddique) merged commit 0e231e0 into microsoft:main Jun 16, 2026
14 of 15 checks passed
Dipika Ranabhat (qubeena07) added a commit to qubeena07/agent-governance-toolkit that referenced this pull request Jun 27, 2026
Address all six blocking issues raised by MohammadHaroonAbuomar and
confirmed by imran-siddique in PR microsoft#3114.

AppArmor profile (agt-sandbox):
- Change all deny rules from x to mrx so ld.so-based invocations
  are blocked in addition to direct exec calls
- Add deny mrx for /tmp/** and /workspace/** to close the
  copy-and-exec bypass vector
- Remove the contradictory deny ptrace read rule at L36 which
  conflicted with the docker-default allow form retained at L60
- Reword the option 3 header to accurately describe exec-level
  denylist scope and note that in-process network access via
  Python urllib or similar is not covered by this profile

Provider (provider.py):
- _apparmor_profile_loaded now checks the mode token and only
  returns True when the profile is in (enforce) mode; a profile
  in (complain) mode is not a confinement boundary
- Add _fallback_apparmor_profile helper that emits a logger.warning
  before returning docker-default so operators have a signal when
  the custom profile was not applied

Scope cleanup:
- Revert agent-governance-rust/agentmesh/src/prompt_injection.rs and
  tests/prompt_injection.rs to their main branch state; these indirect
  injection rule additions are unrelated to the AppArmor work and will
  be submitted as a separate PR to avoid conflicting with microsoft#3069

Tests (test_docker_sandbox.py):
- Add test_returns_false_when_profile_in_complain_mode
- Add test_returns_false_when_mode_token_missing
- Add test_fallback_emits_warning to verify the warning log fires
  when the fallback path is taken
Dipika Ranabhat (qubeena07) added a commit to qubeena07/agent-governance-toolkit that referenced this pull request Jul 17, 2026
A rebase on this branch reverted the indirect and tool output injection
rules from microsoft#3069 along with their test module. Restored both files
from main so instructions_for_ai_reading, system_note_to_assistant,
embedded_tool_directive, and retrieved_doc_override are back in
CONTEXT_RULES.

Reported by MohammadHaroonAbuomar and carloshvp on microsoft#3114.
Tionne Smith (electricwolfemarshmallowhypertext) pushed a commit to electricwolfemarshmallowhypertext/ms-agt that referenced this pull request Oct 12, 2026
…microsoft#3069)

The CONTEXT_RULES family covered first-person social-engineering variants
but had no coverage for the indirect / tool-output injection class: payloads
that arrive inside retrieved content (web pages, emails, RAG documents,
tool results) and address the model directly.

Add four rules in the existing (regex, ThreatLevel, f64, name) tuple format:

  context:instructions_for_ai_reading  High/0.9
    "instructions for the AI/assistant reading/processing this"

  context:system_note_to_assistant     High/0.9
    "system note / note to the assistant:" impersonating a system channel

  context:embedded_tool_directive      Medium/0.8
    HTML-comment-smuggled directive addressed to the AI (<!-- ai: … -->)

  context:retrieved_doc_override       High/0.9
    "this document/page/email instructs you to [inject verb]"
    Scoped to require an explicit injection verb after "you to" so ordinary
    form instructions ("this page asks you to fill in…") do not fire.

All patterns are Rust-regex-safe (no lookarounds or backreferences) and
fit the existing family mechanics — the bare name in the tuple becomes the
stable public rule ID "context:<name>" via family_contains_rule_id /
is_known_built_in_rule_id, exactly like the existing rules.

Adds an indirect_injection_rules test module in tests/prompt_injection.rs
with one positive fixture and one benign-negative fixture per rule, plus
a cross-family type check and a disable-list recognition test. All 10 new
tests pass alongside the existing 63-test suite (373 total, 0 failures).

Scope: CONTEXT_RULES only. DIRECT_RULES, audit chain, policy evaluator,
and governance layer are untouched.

References: OWASP LLM Top 10 LLM01 (Prompt Injection),
MITRE ATLAS AML.T0051.001, and the indirect injection patterns discussed
in issue microsoft#3012.

Assisted-by: Claude Sonnet 4.6

Signed-off-by: AgentGymLeader <agentgymleader@users.noreply.github.com>
Co-authored-by: AgentGymLeader <agentgymleader@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-review:MEDIUM Contributor check flagged MEDIUM risk size/L Large PR (< 500 lines) tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Indirect / tool-output prompt-injection rule family for the prompt-injection detector

2 participants