Back to skill

Security audit

ClawSergeant

Security checks for vulnerabilities and agentic risk

Overview

The skill is broadly aligned with agent training, but it gives LLM-generated content authority to message a real OpenClaw agent and write training state into future agent memory without enough user control.

Install only if you are comfortable with an LLM-generated trainer sending messages to the configured OpenClaw recipient and with training results being stored for later use. Use a test recipient or restricted OpenClaw profile first, avoid sensitive prompts or secrets, keep LLM_BASE_URL pointed at a trusted HTTPS provider, and review or disable any MEMORY.md write path before using it with a real agent workspace.

Vulnerability Patterns
  • 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
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (5)

T01 · Skill Instruction Hijacking

Error
Location
curriculum.py:145
Finding
Untrusted User Intent Is Converted into Instructions for an Autonomous Agent<![CDATA[ ## Vulnerability Details **File Location**: `curriculum.py:145-168`; `trainer.py:304-335`; `main.py:63-70, 136-139` **Vulnerability Type**: Indirect prompt injection and unsafe instruction forwarding **Risk Level**: High ### Vulnerable Code ```python async def design_curriculum(llm: LLMHandler, user_intent: str) -> Curriculum: """Use the LLM to generate a training curriculum from a user intent string.""" prompt = CURRICULUM_DESIGN_PROMPT.format( stage_min=config.STAGE_COUNT_MIN, stage_max=config.STAGE_COUNT_MAX, tasks_min=config.TASKS_PER_STAGE_MIN, tasks_max=config.TASKS_PER_STAGE_MAX, ) conv = Conversation(system_prompt=prompt) conv.add( "user", f"Please design a training curriculum for the following requirement:\n\n" f"{user_intent}", ) logger.info("Generating training curriculum...") data = await llm.chat_json(conv, temperature=config.CURRICULUM_TEMPERATURE) return Curriculum.from_dict(data) ``` ```python if attempt == 1: instruction = ( f"Present the following training task to the Claw agent. " f"Craft a clear, well-structured message that the agent " f"will receive directly.\n\n" f"Task ID: {task.task_id}\n" f"Description: {task.description}\n" f"Scenario:\n{task.scenario}\n" f"Expected behavior: {task.expected_behavior}" ) else: instruction = ( f"The agent's previous response did not fully meet the " f"standards. Here is the evaluation:\n\n" f"Score: {result.score}/10\n" f"Weaknesses: {', '.join(result.weaknesses)}\n" f"Feedback: {result.feedback}\n" f"Suggestion: {result.suggestion}\n\n" f"Generate a follow-up message to help the agent improve. " f"You may rephrase the task, provide hints, or break it " f"into smaller steps — whatever you think will be most " f"effective as a trainer." ) trainer_msg ...[truncated 2436 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Display every generated task, scenario, expected behavior, evaluation criterion, and exact outbound agent message before transmission. 2. Require explicit approval for each exact outbound message rather than approving only a curriculum summary. 3. Enforce a semantic policy that rejects tasks involving credentials, persistence, system configuration, destructive operations, unauthorized communications, or unrelated objectives. 4. Define an allowlisted task schema with bounded field lengths and permitted capability categories. 5. Run the target agent with a restricted tool profile during training, disabling command execution, sensitive filesystem access, credential access, and external messaging unless specifically required. 6. Treat trainer output as an untrusted proposal, not an executable instruction. 7. Record provenance linking every outbound instruction to the approved user request and generated curriculum field. ]]>

T01 · Skill Instruction Hijacking

Error
Location
trainer.py:241
Finding
Raw Agent Responses Can Inject Instructions into Trainer and Evaluator LLMs<![CDATA[ ## Vulnerability Details **File Location**: `trainer.py:241-270, 350-354` **Vulnerability Type**: Cross-agent prompt injection and evaluation manipulation **Risk Level**: High ### Vulnerable Code ```python criteria_text = "\n".join( f"- {c.criterion}: {c.passing_standard}" for c in stage.evaluation_criteria ) eval_conv = Conversation( system_prompt=( "You are an objective AI training evaluator. " "Always respond in valid JSON." ) ) eval_conv.add( "user", EVALUATOR_PROMPT.format( task_description=task.description, expected_behavior=task.expected_behavior, criteria=criteria_text, agent_response=agent_response, ), ) result = await self._llm.chat_json( eval_conv, temperature=config.EVALUATOR_TEMPERATURE ) ``` ```python # Feed the agent's response back into the trainer conversation # so the LLM has full dialogue context for subsequent turns self._trainer_conv.add( "user", f"The Claw agent responded:\n\n{claw_response}", ) ``` The evaluator template embeds the response directly into an instruction-bearing user message: ```python EVALUATOR_PROMPT = """\ Evaluate the Claw agent's response to the given training task. Task requirements: {task_description} Expected behavior: {expected_behavior} Evaluation criteria: {criteria} The Claw agent's response: {agent_response} Provide your evaluation as a JSON object: {{ "passed": true/false, "score": 1-10, "strengths": ["strength 1", "strength 2"], "weaknesses": ["weakness 1", "weakness 2"], "feedback": "Detailed feedback for the agent", "suggestion": "Specific suggestion for improvement" }} """ ``` ### Technical Analysis The target agent's response is untrusted content. It is inserted into the trainer conversation as a new `user` message, which gives it the same conversational role as internal training directives. It is also interpolated directly into the evaluator's user prompt without a robust separation ...[truncated 1579 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat agent responses strictly as untrusted evidence, never as user-role instructions in the trainer conversation. 2. Use a dedicated structured field or tool-call interface for evaluator input where supported. 3. Encode the response as JSON data and instruct the evaluator to analyze only that field. 4. Apply prompt-injection detection and reject responses that attempt to modify the evaluator, trainer, scoring rules, or system instructions. 5. Use an independent deterministic validator for score ranges, field types, and pass conditions. 6. Derive pass/fail status from explicit measurable criteria where possible rather than accepting a model-provided Boolean. 7. Reset or isolate trainer context between attempts so an injected response cannot persist through the stage. 8. Prevent evaluator-generated feedback from being sent onward until it has passed validation. ]]>

T02 · Agent Memory Poisoning

Error
Location
main.py:177
Finding
Attacker-Influenced Training Content Is Intended for Persistent Agent Memory<![CDATA[ ## Vulnerability Details **File Location**: `trainer.py:45-70`; `main.py:177-188`; `SKILL.md:157-160` **Vulnerability Type**: Persistent memory poisoning **Risk Level**: High ### Vulnerable Code ```python BRIEFING_TEMPLATE = """\ You are required to undergo "{curriculum_title}" training to strengthen your \ capabilities in the following areas: {objectives_summary} Target profile after training: {target_persona} The training consists of {stage_count} stages: {stage_list} IMPORTANT: During the training process, you must actively summarize and \ accumulate lessons learned from each exercise. These experiences should be \ remembered for future reference and continuous self-improvement. Treat every \ task as an opportunity to refine your understanding and performance. Confirm that you understand the training objectives and are ready to begin.\ """ ``` ```python STAGE_SUMMARY_TEMPLATE = """\ You have completed Stage {stage_id}: {stage_name} ({passed}/{total} tasks passed). Now, remember this, summarize the key lessons and experiences you gained \ from this stage. What worked well? What patterns or principles did you learn? \ Internalize these insights — they will be essential for the upcoming stages \ and your future performance.\ """ ``` ```python # Write training summary to OpenClaw workspace MEMORY.md stage_details = [ f"Stage {s.id} '{s.name}': " f"{'PASSED' if s.completed else 'FAILED'}" for s in curriculum.stages ] written = learnings.write_to_openclaw_memory( curriculum_title=curriculum.title, target_persona=curriculum.target_persona, stages_passed=completed, stages_total=total_stages, stage_details=stage_details, lessons_dir=lessons_dir, ) ``` The declared behavior also states: ```text After the session completes, a summary is written to ~/.openclaw/workspace/MEMORY.md ... This allows the Claw agent to reference its training history in future sessions. ``` ### Technical Analysis The Skill explicitly a ...[truncated 2344 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic writes to the operational agent's `MEMORY.md`. 2. Store training reports in an isolated, non-executable audit store that is not automatically loaded as agent context. 3. Before any memory update, display the exact proposed text and require explicit user approval. 4. Apply strict semantic filtering to reject durable instructions, persona overrides, safety-policy changes, credential references, and tool-use directives. 5. Record source provenance, timestamp, approving identity, and curriculum identifier for every memory entry. 6. Make memory additions reversible and provide a supported rollback process. 7. Separate observations from instructions so training results cannot become authoritative behavioral rules. 8. Restore and independently audit `learning_logger.py` before enabling the application; ensure it confines writes to an explicitly approved path and does not follow unsafe symbolic links. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
llm_handler.py:59
Finding
Configurable LLM Endpoint Receives the Bearer API Credential without Host Validation<![CDATA[ ## Vulnerability Details **File Location**: `main.py:119-123`; `llm_handler.py:59-82` **Vulnerability Type**: Credential disclosure through an untrusted configurable endpoint **Risk Level**: Medium ### Vulnerable Code ```python llm = LLMHandler( api_key=llm_api_key, base_url=os.getenv("LLM_BASE_URL", "https://api.openai.com/v1"), model=os.getenv("LLM_MODEL", "gpt-4o"), ) ``` ```python def __init__( self, api_key: str, base_url: str = "https://api.openai.com/v1", model: str = "gpt-4o", ): self._api_key = api_key self._base_url = base_url.rstrip("/") self._model = model self._client: httpx.AsyncClient | None = None async def start(self) -> None: """Initialize the HTTP client.""" self._client = httpx.AsyncClient( base_url=self._base_url, headers={ "Authorization": f"Bearer {self._api_key}", "Content-Type": "application/json", }, timeout=httpx.Timeout(120.0, connect=10.0), ) ``` ### Technical Analysis `LLM_BASE_URL` is read from the environment and passed directly to `httpx.AsyncClient`. The bearer credential is configured as a default header for every request made by that client. There is no validation that the URL uses HTTPS, belongs to an approved provider, or matches the provider associated with the credential. An attacker who can alter the environment, `.env` file, deployment configuration, or launch command can redirect API traffic to an attacker-controlled endpoint and collect the bearer token. This issue does not independently give a remote attacker control over the environment. It turns configuration modification into direct credential disclosure and makes unsafe custom-endpoint configuration difficult to detect. ### Attack Path 1. An attacker gains the ability to modify `LLM_BASE_URL` in the process environment or `.env` file. 2. The attacker sets it to an HTTP or HTTPS server under their control. 3. The application loads the ...[truncated 712 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require HTTPS for all non-local endpoints. 2. Maintain an explicit allowlist of approved LLM hosts and reject all other destinations by default. 3. Bind each credential to a configured provider and validate that the endpoint matches that provider. 4. Require an interactive warning and explicit approval before using a custom endpoint. 5. Use separate credentials with minimal quotas and permissions for custom providers. 6. Avoid attaching authorization as a universal client header when redirects or multiple destinations are possible. 7. Disable cross-origin authorization forwarding and explicitly configure a conservative redirect policy. 8. Protect `.env` and deployment configuration with restrictive filesystem permissions and integrity monitoring. ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Dependency Versions Are Not Reproducibly Pinned<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-3` **Vulnerability Type**: Unbounded dependency resolution and supply-chain exposure **Risk Level**: Low ### Vulnerable Code ```text httpx>=0.27 loguru>=0.7 python-dotenv>=1.0 ``` ### Technical Analysis All dependencies use lower-bound-only constraints. Installation can therefore select any later release satisfying the minimum version, including versions that were not reviewed with this project. No lock file or package hashes are included. As a result, two installations performed at different times may resolve to materially different dependency sets. This increases exposure to compromised future releases, unexpected breaking changes, and transitive dependency changes. No evidence was found that the listed package names are typosquatted or intentionally malicious. The issue is the absence of reproducible, integrity-verified dependency resolution. ### Attack Path 1. A future direct or transitive dependency release is compromised or introduces unsafe behavior. 2. A user installs the project with `pip install -r requirements.txt`. 3. The resolver selects the newest version satisfying the lower bound. 4. The unreviewed package executes during installation or is imported at runtime. 5. It inherits the application's process privileges and may access environment credentials, network traffic, or local files. ### Impact Assessment A compromised dependency executes with the same operating-system privileges as the ClawSergeant process. It could access `LLM_API_KEY`, alter LLM traffic, inspect prompts and agent responses, modify generated results, or affect any files accessible to the user. The likelihood is lower than the prompt-boundary findings because exploitation depends on a compromised or vulnerable package release rather than solely on application input. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin direct and transitive dependencies to reviewed exact versions. 2. Generate and commit a lock file using a reproducible dependency-management tool. 3. Require package hashes during installation, such as through a hash-locked requirements file. 4. Use an approved package index and disable untrusted additional indexes. 5. Add automated vulnerability and dependency-integrity scanning. 6. Review and deliberately update dependency pins rather than resolving arbitrary future versions during deployment. 7. Build and test dependencies in an isolated environment before promoting them to production. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (39)

Credential Access

High
Category
Privilege Escalation
Content
*.sage.py

# Environments
.env
.envrc
.venv
env/
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description promises a training/evaluation skill for OpenClaw agents, including curriculum design, iterative training sessions, and capability assessment. The supplied code does not implement any of those behaviors. Instead, it only provides a communication interface to invoke `openclaw agent --to ... --message ...`, capture the subprocess output, and parse the reply text. While such messaging could be a supporting building block for a larger training system, this chunk by itself is materially different in primary purpose and lacks the described training, evaluation, and curriculum features. Therefore this is a clear description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description promises a high-level agent training and evaluation system for OpenClaw agents, including curriculum design, iterative feedback loops, and capability assessment. The supplied code does not implement any of those domain-specific behaviors. Instead, it is a low-level utility for interacting with an OpenAI-compatible chat completion API and maintaining conversation state. While such a wrapper could support a training system, this chunk by itself only provides generic LLM messaging infrastructure. That makes the actual behavior materially narrower and different from the declared primary purpose.

Exfiltration Commands

High
Category
Prompt Injection
Content
class ClawAgent:
    """Send messages to an OpenClaw agent and capture its replies."""

    def __init__(self, recipient: str = ""):
        self._recipient = recipient
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Context Leakage

High
Category
Data Exfiltration
Content
async def chat(
        self, conversation: Conversation, temperature: float = 0.7
    ) -> str:
        """Send the conversation to the LLM and return the assistant reply."""
        if not self._client:
            raise RuntimeError("LLMHandler not started; call start() first")
Confidence
85% confidence
Finding
The chat method transmits the full serialized conversation, including any system prompt and retained message history, to an external provider without any built-in minimization, redaction, or sensitivity filtering. In an agent-training skill, conversations may contain proprietary prompts, evaluation data, or user-supplied secrets, so accidental disclosure to the LLM backend is a realistic confidentiality risk.

Exfiltration Commands

High
Category
Prompt Injection
Content
async def chat(
        self, conversation: Conversation, temperature: float = 0.7
    ) -> str:
        """Send the conversation to the LLM and return the assistant reply."""
        if not self._client:
            raise RuntimeError("LLMHandler not started; call start() first")
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Context Leakage

High
Category
Data Exfiltration
Content
async def chat_json(
        self, conversation: Conversation, temperature: float = 0.3
    ) -> dict:
        """Send the conversation and parse the reply as JSON.

        Uses the response_format API parameter to enforce valid JSON output.
        """
Confidence
85% confidence
Finding
The chat_json method has the same context-leakage issue as chat: it forwards full conversation state to an external service and only constrains output format, not input sensitivity. Because this skill is designed for iterative agent training and evaluation, accumulated dialogue may include internal rubrics, test cases, or confidential operational context that should not be broadly disclosed.

Credential Access

High
Category
Privilege Escalation
Content
def _env_setup() -> tuple[str, str, str, str]:
    """Load .env and return (api_key, base_url, model, recipient)."""
    load_dotenv()
    api_key = os.getenv("LLM_API_KEY", "")
    base_url = os.getenv("LLM_BASE_URL", "https://api.openai.com/v1")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def _env_setup() -> tuple[str, str, str, str]:
    """Load .env and return (api_key, base_url, model, recipient)."""
    load_dotenv()
    api_key = os.getenv("LLM_API_KEY", "")
    base_url = os.getenv("LLM_BASE_URL", "https://api.openai.com/v1")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def _env_setup() -> tuple[str, str, str, str]:
    """Load .env and return (api_key, base_url, model, recipient)."""
    load_dotenv()
    api_key = os.getenv("LLM_API_KEY", "")
    base_url = os.getenv("LLM_BASE_URL", "https://api.openai.com/v1")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
api_key, base_url, model, *_ = _env_setup()
    if not api_key:
        sys.exit("[FAIL] LLM_API_KEY not set in .env")

    print(f"\n=== Phase 1: LLM Connection Test ===")
    print(f"Base URL : {base_url}")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
api_key, base_url, model, *_ = _env_setup()
    if not api_key:
        sys.exit("[FAIL] LLM_API_KEY not set in .env")

    print(f"\n=== Phase 1: LLM Connection Test ===")
    print(f"Base URL : {base_url}")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
api_key, base_url, model, *_ = _env_setup()
    if not api_key:
        sys.exit("[FAIL] LLM_API_KEY not set in .env")

    print(f"\n=== Phase 1: LLM Connection Test ===")
    print(f"Base URL : {base_url}")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
api_key, base_url, model, *_ = _env_setup()
    if not api_key:
        sys.exit("[FAIL] LLM_API_KEY not set in .env")

    print(f"\n=== Phase 1: LLM Connection Test ===")
    print(f"Base URL : {base_url}")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
api_key, base_url, model, *_ = _env_setup()
    if not api_key:
        sys.exit("[FAIL] LLM_API_KEY not set in .env")

    print(f"\n=== Phase 1: LLM Connection Test ===")
    print(f"Base URL : {base_url}")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
eval_conv = Conversation(
            system_prompt=(
                "You are an objective AI training evaluator. "
                "Always respond in valid JSON."
            )
        )
        eval_conv.add(
Confidence
70% confidence
Finding
Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill describes capabilities involving environment variables, file writes, network access, and shell/CLI execution, but it does not declare any tool scope or permission boundaries. This creates an implicit over-privilege risk: a caller or host may invoke the skill without clear restrictions, increasing the chance of unintended command execution, data access, or outbound transmission.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The invocation text is broad enough to match many generic requests about improving or evaluating AI agents, which can cause the skill to activate in contexts where the user did not intend persistent logging, network use, or agent communication. Over-broad triggering increases the risk of unnecessary exposure of prompts, transcripts, and operational side effects.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill states that evaluations, stage results, and summaries are written to local lesson logs and MEMORY.md, but it does not prominently warn users that transcripts and outputs will be persisted. This can lead to unintentional storage of sensitive prompts, agent responses, credentials, or proprietary data in locations that may later be accessed by other tools or users.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This code posts the full serialized conversation to a remote chat completions endpoint, which may include user-provided or system data. While the module docstrings describe LLM communication, there is no user-facing disclosure, confirmation, or explicit warning in the file about external transmission of conversation contents.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
The code pulls an environment-configured recipient for a real agent and later uses learning memory integration, giving it the ability to target external agent endpoints and persist outputs into shared workspace state. Those capabilities exceed a narrowly scoped local curriculum designer and increase the chance of unintended interaction with production-like agents or contamination of persistent memory.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The skill persists a training summary into an OpenClaw workspace MEMORY.md file, which changes state outside the immediate training run and can influence future agent behavior or downstream processes. In a training/evaluation tool, writing into shared workspace memory is more sensitive than ordinary result export because it creates durable side effects in another system context.

External Transmission

Medium
Category
Data Exfiltration
Content
"""Load .env and return (api_key, base_url, model, recipient)."""
    load_dotenv()
    api_key = os.getenv("LLM_API_KEY", "")
    base_url = os.getenv("LLM_BASE_URL", "https://api.openai.com/v1")
    model = os.getenv("LLM_MODEL", "gpt-4o")
    recipient = os.getenv("CLAW_RECIPIENT", "")
    return api_key, base_url, model, recipient
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
"""Load .env and return (api_key, base_url, model, recipient)."""
    load_dotenv()
    api_key = os.getenv("LLM_API_KEY", "")
    base_url = os.getenv("LLM_BASE_URL", "https://api.openai.com/v1")
    model = os.getenv("LLM_MODEL", "gpt-4o")
    recipient = os.getenv("CLAW_RECIPIENT", "")
    return api_key, base_url, model, recipient
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
"""Load .env and return (api_key, base_url, model, recipient)."""
    load_dotenv()
    api_key = os.getenv("LLM_API_KEY", "")
    base_url = os.getenv("LLM_BASE_URL", "https://api.openai.com/v1")
    model = os.getenv("LLM_MODEL", "gpt-4o")
    recipient = os.getenv("CLAW_RECIPIENT", "")
    return api_key, base_url, model, recipient
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.