Back to skill

Security audit

Claude Managed Agents

Security checks for vulnerabilities and agentic risk

Overview

The skill appears purpose-aligned, but it gives broad remote-agent control and has weak safeguards around API-key destination, networking, file transfer, and deletion.

Install only if you need full Claude Managed Agents lifecycle control from this machine. Keep ANTHROPIC_API_BASE_URL unset unless you intentionally use a trusted HTTPS gateway, prefer limited networking with explicit hosts, avoid uploading sensitive files or secrets unless approved, and verify exact IDs before archive or delete commands.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/managed_agents.py:27
Finding

API credentials can be transmitted to an attacker-controlled or plaintext endpoint

Content
View full analysis

Vulnerability Details

File Location: scripts/managed_agents.py:27, scripts/managed_agents.py:178-193, scripts/managed_agents.py:207-231, scripts/managed_agents.py:342-351, scripts/managed_agents.py:408-417, and scripts/managed_agents.py:877-886
Vulnerability Type: Arbitrary credential destination and insufficient transport validation
Risk Level: High

Vulnerable Code

python
API_BASE_URL = os.environ.get("ANTHROPIC_API_BASE_URL", "https://api.anthropic.com")
python
class ManagedAgentsClient:
    def __init__(self, *, backend: str = "auto", api_key_env: str = "ANTHROPIC_API_KEY", timeout: float = DEFAULT_TIMEOUT):
        self.api_key_env = api_key_env
        self.timeout = timeout
        self.api_key = os.environ.get(api_key_env)
        if not self.api_key:
            raise CliError(f"{api_key_env} is not set")

        if backend == "auto":
            backend = "sdk" if Anthropic is not None else "http"
        if backend not in {"sdk", "http"}:
            raise CliError(f"unsupported backend: {backend}")
        if backend == "sdk" and Anthropic is None:
            raise CliError("anthropic Python SDK is not installed; use --backend http or install `anthropic`")

        self.backend = backend
        self.sdk = Anthropic(api_key=self.api_key, timeout=timeout) if backend == "sdk" else None
python
    def _request(
        self,
        method: str,
        path: str,
        *,
        query: Optional[dict[str, Any]] = None,
        payload: Optional[dict[str, Any]] = None,
        raw_data: Optional[bytes] = None,
        content_type: Optional[str] = None,
        accept: str = "application/json",
        betas: Optional[list[str]] = None,
    ) -> Any:
        url = f"{API_BASE_URL.rstrip('/')}{path}"
        if query:
            encoded = urllib.parse.urlencode({k: v for k, v in query.items() if v is not None}, doseq=Tru
...[truncated 5510 chars]
Remediation
View remediation

Remediation Suggestions

  1. Parse the base URL with urllib.parse.urlsplit before initializing either backend.
  2. Require the https scheme for every authenticated production request.
  3. Allow api.anthropic.com by default and reject other hosts unless the operator provides an explicit custom-gateway opt-in.
  4. If custom gateways are supported, require a separate hostname allowlist and document that API credentials will be disclosed to the gateway.
  5. Reject URLs containing user information, fragments, unexpected ports, malformed hostnames, or ambiguous encoded components.
  6. Disable automatic redirects or validate every redirect target before forwarding authentication headers. Never forward x-api-key across origins.
  7. Centralize validated URL construction so _request, download_file, and stream_events cannot bypass the policy.
  8. Apply equivalent base-URL restrictions when constructing the Anthropic SDK client.
  9. Make validation mandatory at client initialization rather than an advisory doctor report.
  10. Add tests proving that plaintext URLs, unapproved hosts, embedded credentials, and cross-origin redirects cannot receive the API key.

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
references/quickstart.md:39
Finding

Quickstart provisions unrestricted network access for a task that requires no network connectivity

Content
View full analysis

Vulnerability Details

File Location: references/quickstart.md:39-48
Vulnerability Type: Excessive managed-agent network privileges
Risk Level: Medium

Vulnerable Configuration

bash
python3 ~/.openclaw/skills/claude-managed-agents/scripts/managed_agents.py \
  environment create \
  --name "quickstart-env" \
  --network unrestricted

The quickstart previously creates the agent with the full built-in toolset:

bash
python3 ~/.openclaw/skills/claude-managed-agents/scripts/managed_agents.py \
  agent create \
  --name "Coding Assistant" \
  --model claude-sonnet-4-6 \
  --system "You are a helpful coding agent." \
  --agent-toolset

The example task is:

bash
python3 ~/.openclaw/skills/claude-managed-agents/scripts/managed_agents.py \
  session send \
  --session-id sess_123 \
  --message "Create a Python script that prints the first 20 Fibonacci numbers."

Technical Analysis

The documented happy path grants unrestricted outbound networking to a managed environment and combines it with a full built-in agent toolset. The demonstrated Fibonacci task is entirely local and does not need network access.

This violates least privilege by exposing arbitrary network egress as the default introductory configuration. Managed-agent inputs can include user messages, uploaded files, repository content, MCP responses, package content, and other externally controlled data. If such content causes prompt injection or malicious tool behavior, unrestricted networking provides a direct exfiltration and command-and-control channel.

Although the project elsewhere recommends limited networking for production-oriented environments, users are likely to copy the quickstart as the canonical default. The documented configuration therefore grants privileges beyond those necessary for the declared example.

Attack Path

  1. An operator follows the documented happy path and creates ...[truncated 1230 chars]
Remediation
View remediation

Remediation Suggestions

  1. Change the quickstart to disable networking or use a limited network configuration with no allowed hosts for the Fibonacci example.
  2. Enable only the built-in tools required for the demonstrated task instead of using the full default toolset.
  3. Present unrestricted networking as an advanced, explicit opt-in rather than the happy-path default.
  4. Require operators to identify the specific external services needed before adding allowed hosts.
  5. Recommend approval-gated policies such as bash=ask, write=ask, and edit=ask when broad tools are enabled.
  6. Add a warning that mounted files, vault material, repository credentials, and session content may become reachable by network-enabled tools.
  7. Include a separate limited-network example for tasks that genuinely require package registries or external APIs.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (34)

Tainted flow: 'request' from os.environ.get (line 415, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The request target is built from API_BASE_URL, which is sourced from an environment variable and used directly for outbound authenticated requests carrying the Anthropic API key. In a skill context that manages agents and uploads content, this allows credential and data exfiltration to an attacker-controlled endpoint if the environment variable is poisoned or inherited from an untrusted environment.

Content

Scanner excerpt · scripts/managed_agents.py (reported line 231)May include surrounding context.

python
request = urllib.request.Request(url=url, data=data, headers=headers, method=method.upper())
        try:
            with urllib.request.urlopen(request, timeout=self.timeout) as response:
                raw = response.read().decode("utf-8")
                if accept == "text/event-stream":
                    return raw

Tainted flow: 'request' from os.environ.get (line 415, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

File downloads use the same environment-controlled API base and attach the API key header, enabling authenticated requests to arbitrary endpoints if the base URL is overridden. In this skill, the downloaded content is then written to disk, so a poisoned base URL can both leak credentials and deliver attacker-controlled payloads into the local filesystem.

Content

Scanner excerpt · scripts/managed_agents.py (reported line 351)May include surrounding context.

python
}
        request = urllib.request.Request(url=url, headers=headers, method="GET")
        try:
            with urllib.request.urlopen(request, timeout=self.timeout) as response:
                return response.read()
        except urllib.error.HTTPError as exc:
            raw = exc.read().decode("utf-8", errors="replace")

Tainted flow: 'request' from os.environ.get (line 415, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
91% confidence
Finding

The event-stream connection also uses an environment-derived base URL and sends authenticated requests to it. Because this command streams and processes remote-controlled event data in a privileged agent-management workflow, an attacker-controlled host could capture credentials and feed misleading or malicious event content to the operator.

Content

Scanner excerpt · scripts/managed_agents.py (reported line 417)May include surrounding context.

python
}
        request = urllib.request.Request(url=url, headers=headers, method="GET")
        try:
            with urllib.request.urlopen(request, timeout=self.timeout) as response:
                data_lines: list[str] = []
                for raw_line in response:
                    line = raw_line.decode("utf-8").rstrip("\r\n")

Context Leakage

High
Category
Data Exfiltration
Confidence
86% confidence
Finding

The skill is designed to send session messages, interrupts, confirmations, and custom tool results into remote managed-agent sessions, which creates a direct path for local context or sensitive operator input to be forwarded externally. Because the description is broad and there is no strong data-minimization warning, users may unintentionally leak repository contents, secrets, or internal operational context into remote sessions.

Content

Scanner excerpt · SKILL.md (reported line 3)May include surrounding context.

md
---
name: claude-managed-agents
description: Manage Claude Managed Agents end to end through a Python helper CLI, with ant CLI equivalents documented as a secondary path. Use this whenever the user wants to create, update, list, archive, or inspect Claude Managed Agents agents, environments, sessions, or event streams; configure built-in tools, MCP servers, skills, packages, or networking; send session messages, interrupts, confirmations, or custom tool results; or work with Anthropic's managed-agents beta lifecycle from this machine.
compatibility:
  tools: Read, Edit, Bash
  dependencies: Python 3, ANTHROPIC_API_KEY, optional anthropic SDK, optional ant CLI

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 83)May include surrounding context.

md
- `scripts/managed_agents.py`

Context Leakage

High
Category
Data Exfiltration
Confidence
85% confidence
Finding

Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Content

Scanner excerpt · scripts/managed_agents.py (reported line 1369)May include surrounding context.

python
session_delete.add_argument("--session-id", required=True)
    session_delete.set_defaults(func=handle_session_delete)

    session_send = session_subparsers.add_parser("send", help="Send session events")
    _add_common_transport_flags(session_send)
    session_send.add_argument("--session-id", required=True)
    session_send.add_argument("--event-json", action="append", default=[])

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill exposes powerful capabilities including environment access, file read/write, MCP interaction, and networked API operations, but it does not declare any explicit tool scope or permissions boundaries. In a skill that can create, update, delete, upload, download, and stream remote agent/session state, missing scope declarations increases the chance of overbroad invocation and unintended high-impact actions.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The invocation description is extremely broad and encourages use for nearly any managed-agent lifecycle action from the machine, including networking, sessions, MCP servers, and custom tool results. This can cause the skill to trigger in situations where the user did not intend such expansive authority, increasing the risk of unsafe automation or accidental destructive operations.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 18)May include surrounding context.

md
## What this skill handles

- agents
  - create
  - update
  - retrieve
  - list

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill advertises file upload, download, deletion, and mounting into sessions, but it does not prominently warn that these actions may transfer local data to a remote service and persist artifacts outside the local machine. In a managed-agents context, this creates real risk of unintentional disclosure of sensitive files, credentials, or proprietary repository contents.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The recipe documentation includes archive and delete commands for environments without any caution, confirmation guidance, or note about irreversibility. In a skill specifically designed to manage Claude Managed Agents resources end to end, users may copy-paste these commands directly and unintentionally destroy active environments or lose access to important resources.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The session archive/delete examples are presented as normal recipes with no warning about destructive consequences, which can lead operators to terminate or remove active sessions unintentionally. Because this skill is meant to manage live agents, environments, sessions, and event streams, omission of safety context increases the chance of operational disruption or data loss.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/event-model.md (reported line 27)May include surrounding context.

md
## Basic send and stream loop

1. create session
2. send `user.message`
3. stream events
4. stop on `session.status_idle` or `session.error`

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file describes uploading local files to a managed service and deleting files via the Files API, which can affect user data and transmit local content off-system. The reference provides commands and technical notes, but it does not include a clear warning or disclosure about privacy implications of uploads or the irreversible nature of deletion.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/files-api.md (reported line 43)May include surrounding context.

md
--only-id)

python3 ~/.openclaw/skills/claude-managed-agents/scripts/managed_agents.py \
  session create \
  --agent-id agent_123 \
  --environment-id env_123 \
  --resource-json "{\"type\":\"file\",\"file_id\":\"${FILE_ID}\",\"mount_path\":\"/workspace/data.csv\"}"

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/lifecycle-recipes.md (reported line 5)May include surrounding context.

Agents

Create with only a limited tool subset

bash
python3 ~/.openclaw/skills/claude-managed-agents/scripts/managed_agents.py \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The quickstart tells users to export an API key into their shell environment but provides no warning about protecting credentials from shell history, shared terminals, process inspection, or accidental inclusion in logs and scripts. In a security-sensitive operations skill, normalizing secret handling without guardrails increases the chance of credential leakage and unauthorized API use.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/quickstart.md (reported line 31)May include surrounding context.

--allowed-host api.example.com

text

### 1. Create an agent

```bash
python3 ~/.openclaw/skills/claude-managed-agents/scripts/managed_agents.py \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The example recommends creating an environment with --network unrestricted and gives no warning about the security consequences. This can enable broad outbound access from agent-executed workloads, increasing the risk of data exfiltration, unexpected internet access, or misuse of tools/packages in a less constrained environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The quickstart demonstrates uploading a local file and later describes direct HTTP fallback and streaming, but it does not warn that local file contents, prompts, and session data may be transmitted to remote services. Users may unknowingly send sensitive data off-host, which is especially risky in a managed-agents workflow designed to handle arbitrary local resources.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The client exposes agent deletion via a direct DELETE call, and corresponding handlers invoke it without any confirmation prompt or visible warning to the operator. The same pattern is used for other delete methods in this file, making irreversible remote deletions easy to trigger without disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The environment delete method performs an irreversible remote deletion through the API, and the command handler exposes it without any confirmation or cautionary messaging. This is a destructive operation in a code file with no visible disclosure to the user.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The file delete operation removes a Files API object through a DELETE request, but the code provides no prompt, warning, or explanatory output before doing so. This is a destructive action with no visible disclosure in the implementation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The session delete method performs remote deletion and is invoked by the CLI without any confirmation or warning. Because deletion is destructive and potentially irreversible, the absence of disclosure meets the missing-warning criterion for code files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The download handler creates parent directories and writes remote file content directly to a local path, but there is no confirmation prompt, warning print, or inline disclosure that the command will modify the local filesystem. For a code file, this is a safety-relevant file write operation that lacks visible user disclosure in the implementation.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
tests/test_managed_agents.py:15