Skip to content

feat(rules): add AI600-AI900 security rules for agents, RAG, API keys, and output handling - #92

Open
mmustafasenoglu wants to merge 2 commits into
ParzivalHack:mainfrom
mmustafasenoglu:feat/ai600-900-security-rules
Open

feat(rules): add AI600-AI900 security rules for agents, RAG, API keys, and output handling#92
mmustafasenoglu wants to merge 2 commits into
ParzivalHack:mainfrom
mmustafasenoglu:feat/ai600-900-security-rules

Conversation

@mmustafasenoglu

Copy link
Copy Markdown

Summary

Adds 18 new AI/LLM security rules covering understimated attack surfaces: unsafe agent behavior, RAG pipeline security, hardcoded API keys, and unsafe output handling.

Motivation

Closes #91

The existing ruleset covers prompt injection and model deserialization well, but modern LLM applications have expanded attack surfaces that weren't being caught. This adds coverage for:

Changes

AI600 - Unsafe Agent Behavior & Tool Poisoning

  • AI601: Unrestricted web browsing in agents (SSRF risk)
  • AI602: Subprocess execution via agent tools (arbitrary command execution)
  • AI603: Unrestricted file write capability in agents
  • AI604: Indirect prompt injection via unsanitized tool output
  • AI605: Verbose agent logging exposing sensitive data
  • AI606: Disabled parsing error handling leaking internal state

AI700 - RAG Security

  • AI701: Unvalidated document ingestion (embedding poisoning)
  • AI702: Low similarity threshold retrieving adversarial content
  • AI703: Context injection without size limits (DoS)
  • AI704: Embedding models from untrusted sources

AI800 - API Key & Credential Management

  • AI801: Hardcoded OpenAI API keys
  • AI802: Hardcoded Anthropic API keys
  • AI803: API keys in URL query parameters
  • AI804: Hardcoded Cohere API keys

AI900 - Output Handling & DoS

  • AI901: Unsafe YAML parsing of LLM output (RCE via yaml.load)
  • AI902: JSON parsing without size limits (memory exhaustion)
  • AI903: exec/eval of LLM-generated code
  • AI904: Unsanitized LLM output rendered as HTML (XSS)

Also adds 4 new taint sources/sinks (AITS11-12, AISK11-12) for RAG vector store retrieval and agent web tool flows.

Testing

  • All new rules have TOML metadata validation
  • Pattern matching tests for each rule category
  • Exclude pattern tests for safe alternatives (e.g., yaml.safe_load)
  • TOML file validates successfully (44 total rules, 12 taint sources, 12 sinks)

…API keys, and output handling

Adds 18 new rules covering:
- AI600: Unsafe agent behavior & tool poisoning (web browsing, subprocess, file write, indirect injection)
- AI700: RAG security (embedding poisoning, context overflow, untrusted sources)
- AI800: API key management (OpenAI, Anthropic, Cohere hardcoded keys)
- AI900: Output handling & DoS (YAML unsafe load, JSON DoS, exec/eval of LLM output, XSS)

Also adds 4 new taint sources/sinks for RAG and agent web tool flows.

Closes ParzivalHack#91
Copilot AI lite review requested due to automatic review settings August 3, 2026 11:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@ParzivalHack ParzivalHack added the enhancement New feature or request label Aug 7, 2026
@desimetallica

Copy link
Copy Markdown
Collaborator

Hello @mmustafasenoglu thanks for adding the AI600-AI900 rules. The security coverage is valuable, but I recommend requesting changes before merging because several rules currently produce false positives or do not match their stated behavior.

Some comments:

  • AI601: the regex misses common multiline/separately-defined agent tools, flags unrelated code, and its test example does not match the regex. AITS12 also taints every requests.get() response, while AISK11 duplicates the existing SSRF sink.
  • AI603: open\s*\(.*['"]w['"]|['"]a['"] has an ungrouped alternation and matches unrelated code such as mode = "a". It also flags ordinary file writes without establishing agent context.
  • AI604, AI903, AI904: broad regex alternatives create significant false positives. In particular, AI903 and AI904 can match any line containing response, output, or completion.
  • AI702: the rule claims to detect a low similarity threshold, but the pattern checks k=, which is the number of retrieved documents, not a similarity threshold.
  • AI704, AI701, AI602, AI605, AI703, AI902: these rules could flag common legitimate APIs without proving that they are used in an agent/RAG/security-sensitive context.
  • AI704 and AITS11: AITS11 contains a malformed function path and will not reliably match normal instance calls such as vectorstore.similarity_search(...).

The tests currently focus mostly on positive regex matches. Please add negative tests for ordinary HTTP clients, subprocess usage, JSON parsing, trusted embedding models, normal file writes, sanitized HTML, and multiline code. Taint-flow tests should also verify that trusted constants do not become tainted and that duplicate AI501/AI601 findings are avoided.

I suggest narrowing or removing the broad regex rules and using AST/taint analysis where the rule depends on data flow or agent context. After these corrections, the proposed rule categories should be much more useful with less noise.

- Remove AI601/AI603/AI604: line-based regex cannot establish agent
  context; SSRF and file access already covered by AI501/AISK08 and
  AI502/AISK09 taint analysis
- Remove AITS12/AISK11: AITS12 tainted every requests.get response,
  AISK11 duplicated the existing AISK08 sink
- AI602: require shell=True instead of flagging all subprocess usage
- AI702: pattern now checks score_threshold (was checking top-k count)
- AI902/AI903/AI904: narrow patterns to LLM-output variables; drop
  broad .*response|.*output|.*completion alternatives that matched
  any line containing those words
- AI904: exclude sanitized output (sanitize|bleach)
- AITS11: fix malformed function path, match instance calls via
  .similarity_search
- Add negative tests: plain HTTP clients, subprocess without shell,
  plain json.loads, other embedding models, sanitized HTML, top-k
  without threshold, plain eval, multiline taint flow
- Taint tests: trusted constants stay untainted, no duplicate
  AI501/AI601 findings
Copilot AI review requested due to automatic review settings August 14, 2026 14:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@mmustafasenoglu

Copy link
Copy Markdown
Author

Thanks for the detailed review, @desimetallica — you're right on every point. I've reworked the rules and addressed all of it in 2a73c99.

Removed (couldn't reliably prove agent context with line-based regex, or duplicated existing coverage):

  • AI601 + AITS12 + AISK11: the regex missed multiline tool definitions and the test example never matched. Agent-side SSRF is already covered by AI501/AISK08 taint analysis, and AISK11 was a duplicate of AISK08. AITS12 tainting every requests.get() response was too broad, so it's gone too.
  • AI603: the ungrouped alternation did match mode = "a". Agent-side filesystem access is already covered by AI502/AISK09.
  • AI604: unsanitized tool-output → prompt is a data-flow issue; the equivalent flow is already covered by the AITS04 → AISK01 (AI101) taint path.

Narrowed:

  • AI602: now only fires on subprocess.(run|call|Popen|check_output)(...) with shell=True, so ordinary subprocess usage is ignored.
  • AI702: you're right that k= is the retrieval count, not a similarity threshold. The pattern now looks for an explicit score_threshold=0.x instead.
  • AI902 / AI903 / AI904: the .*response|.*output|.*completion alternatives matched any line containing those words — that was bad. Patterns are now scoped to actual LLM-output variables (e.g. eval(llm_output), json.loads(response)), and AI904 got a sanitize|bleach exclude for sanitized HTML.
  • AITS11: fixed the malformed path (stray space) and switched to .similarity_search so normal instance calls like vectorstore.similarity_search(...) match.

Lowered confidence / clarified: AI605, AI701, AI703, AI704 now carry confidence = "Low" with descriptions that no longer overclaim agent/RAG context.

New tests (68 in total now):

  • Negative: plain HTTP clients, subprocess without shell=True, plain json.loads/eval, trusted embedding models, sanitized innerHTML, top-k without threshold, verbose=False, plain file reads, multiline requests.get.
  • Taint-flow: trusted constant URLs stay untainted; tainted URL → requests.get fires AI501 but not AI601 (no duplicate findings); AITS11 retrieval → prompt flow fires AI101.

The broader rules that depend on data flow or agent context are now taint-driven rather than regex-driven, so the remaining regexes should produce much less noise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Good First Issue: Add a new AI/LLM security rule to our ruleset

4 participants