Skip to content

SAF-T1001: fix Sigma unicode detection and address review findings - #213

Open
fkautz wants to merge 1 commit into
secure-agentic-framework:mainfrom
fkautz:fix/saf-t1001-detection-and-review
Open

fkautz wants to merge 1 commit into
secure-agentic-framework:mainfrom
fkautz:fix/saf-t1001-detection-and-review

Conversation

@fkautz

@fkautz fkautz commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Addresses the SAF-T1001 (Tool Poisoning Attack) technique review. The headline fix is the detection rule: its invisible-character patterns never matched real payloads.

Detection fix (primary)

  • The Sigma rule listed patterns like '*\uXXXX*'. A production backend treats those as the literal 6-character string , not the U+200B codepoint, so a description containing a genuine zero-width / bidirectional / Unicode-tag character matched none of them — exactly the attack the page documents.
  • Replaced them with a tool_description|re regex over the actual codepoints (zero-width, bidirectional overrides/isolates, and the U+E0000-U+E007F tag range).
  • Reworked test_detection_rule.py to model real backend semantics (dropped the non-standard unicode-escape decode that was making the broken rule look green) and added test-logs.json cases carrying real invisible characters. Now 13/13 pass with full pattern coverage, and the test reflects production behavior.

Other review findings

  • References: added the six incident citations that were cited in-body but missing (WhatsApp MCP, GitHub MCP, Oligo CVE-2025-49596, mcp-remote CVE-2025-6514, GBHackers Gmail, invariantlabs-ai/mcp-scan) plus the RADE source; reconciled the inlined rule with the shipped file (author, repo URL).
  • ATT&CK mapping: kept Initial Access as primary, added supporting tactics for the documented persistence/exfiltration/priv-esc behaviors, and replaced the self-flagged "conceptually similar" T1055 with T1027 (Obfuscated Files or Information).
  • Description: expanded to explain the mechanism (render-vs-context divergence, tokenization, session-persistent injection).
  • RADE: corrected the term (Retrieval-Agent Deception, not "Retrieval-Augmented Data Exfiltration") and attributed it to arXiv:2504.03767.
  • Removed RFC-2360-barred hype language.

Test

python3 techniques/SAF-T1001/test_detection_rule.py
# Test Summary: 13/13 tests passed (100.0%)

🤖 Generated with Claude Code

@fkautz
fkautz force-pushed the fix/saf-t1001-detection-and-review branch 2 times, most recently from d58cf6e to 20455cb Compare July 2, 2026 04:36
Fix the Sigma rule's invisible-character detection, which never matched
real payloads: the literal '\uXXXX' globs were matched as literal text by
production backends. Replace them with a tool_description|re regex over the
actual codepoints (zero-width, bidirectional, and the U+E0000-U+E007F tag
range). Rework the test harness to model real backend semantics (drop the
unicode-escape hack) and add test-log cases carrying genuine invisible
characters. Result: 13/13 pass with full pattern coverage.

Also address the rest of the review:
- Complete References with the six missing incident citations plus the
  RADE source; reconcile the inlined rule with the shipped file.
- Reconcile the ATT&CK mapping: keep Initial Access primary, add supporting
  tactics, and replace the loose T1055 with T1027 (Obfuscated Files).
- Expand the Description with the technical mechanism.
- Correct RADE (Retrieval-Agent Deception, arXiv:2504.03767) and remove
  hype language.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederick F. Kautz IV <fkautz@alumni.cmu.edu>
@fkautz
fkautz force-pushed the fix/saf-t1001-detection-and-review branch from 20455cb to a76534f Compare July 2, 2026 05:37
@Santoshkumarpuppala

Copy link
Copy Markdown

The escape-literal bug is real, and the two halves are the same class: the rule read as enforcing and matched nothing, and the test read as green because pattern.encode().decode('unicode-escape') was doing work a real backend does not do. Dropping that decode is the half I would want other people to copy — fixing the rule alone would have left the test still lying about it.

Small thing in case it was simply missed in a batch: T1002–T1005 (#214#217) all merged on 2026-07-27, and this one has been open since 2 July.

One coverage note, so the technique page does not over-claim once this lands. After the fix the detection is a regex over real codepoints, which closes the invisible-character class properly. It does not touch the class where the payload is plainly visible but not in a form the pattern matches. Measured against a description scanner I maintain (Norviq, https://github.com/norviq-dev/norviq), all of these scan clean: base64 of the instruction, ROT13, the target path spelled out in words instead of punctuation, and the same instruction in plain Spanish or German. Those are complementary to what this rule covers rather than competing with it — but a page that documents the technique and ships a Sigma rule invites the reading that the rule covers the technique. The payloads and the run they came from are at https://norviq.dev/blog/the-mcp-server-you-approved/ if they are useful as fixtures.

Suggestion: land it as-is, then add the missed cases as explicitly known-negative fixtures rather than leaving them undocumented. Asserting the current behaviour on a payload you know you miss is what keeps the coverage claim honest as the rule evolves, and it is how the next person notices when the rule moves.

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.

2 participants