Back to skill

Security audit

Supervised Agentic Loop

Security checks for vulnerabilities and agentic risk

Overview

This skill is not clearly malicious, but it gives an autonomous code loop broad local mutation authority while some advertised safety boundaries are under-enforced.

Install only in a disposable clone or clean worktree, not in a repository with valuable uncommitted work. Treat the metric command and any provided agent or LLM callable as trusted code paths. Leave Telegram and remote LLM review unset unless you are comfortable sending alert or session details outside the machine.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def _run_metric_command(self) -> str:
        """Execute the metric command and return output."""
        try:
            proc = subprocess.run(
                shlex.split(self.config.metric_command),
                shell=False,
                cwd=self.config.work_dir,
Confidence
91% confidence
Finding
The code executes `self.config.metric_command` via `subprocess.run(...)` after only tokenizing it with `shlex.split`. While `shell=False` avoids classic shell metacharacter injection, it still permits execution of any attacker-controlled program/arguments if `metric_command` is untrusted, which can lead to arbitrary local command execution in the loop's working directory. In this skill's context, the loop is explicitly autonomous and repeatedly invokes the configured command, which increases risk because a dangerous command could be executed many times.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"""Gate 3: Run tests and check they pass."""
    result = VerificationResult()
    try:
        proc = subprocess.run(
            shlex.split(test_command),
            shell=False,
            cwd=cwd,
Confidence
93% confidence
Finding
The code executes a caller-supplied test_command via subprocess.run after only shlex splitting it. Although shell=False prevents shell metacharacter injection, this still permits arbitrary local command execution if an untrusted agent, config, or user can influence test_command, which is especially risky in a self-improving agent loop that may generate or mutate its own verification commands.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cmd = f"{linter} {file_args}"

    try:
        proc = subprocess.run(
            shlex.split(cmd), shell=False, capture_output=True, text=True, timeout=timeout
        )
        passed = proc.returncode == 0
Confidence
89% confidence
Finding
The lint command is built as a string from linter plus file paths and then executed with subprocess.run. shell=False avoids classic shell injection, but untrusted file names beginning with option-like prefixes or attacker-controlled paths can still alter linter behavior, and invoking external tools on attacker-chosen files creates a command execution surface inside the agent workflow.

Tp4

High
Category
MCP Tool Poisoning
Confidence
82% confidence
Finding
The skill markets itself as local-by-default and safety-focused, but it also includes optional outbound Telegram alerting and monitor telemetry features, and the async LLM review appears overstated relative to actual integration in the main loop. That mismatch can cause operators to over-trust the safety model, misconfigure deployment boundaries, or unknowingly permit data to leave the host when alerting is enabled.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The embedded SKILL.md grants broad `external_cli_execution` and `network_requests` capabilities while the surrounding text frames the system as local-by-default and narrowly scoped. In an autonomous self-improving loop, those capabilities materially expand what agent-generated experiments can do, creating a real mismatch between stated safety boundaries and effective authority.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The justification only describes limited HTTP HEAD checks, but the declared capability is generic `network_requests`, which typically permits much broader outbound access. In a self-modifying autonomous workflow, that gap can enable exfiltration, dependency fetching, or unreviewed communication beyond the claimed narrow purpose.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
`metric_command` is defined as an arbitrary shell command and is executed as part of the autonomous loop, which gives the skill a powerful execution primitive. If influenced by untrusted input or misconfigured tasks, it can run destructive commands locally, invoke network tools, or bypass intended verification boundaries.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The design repeatedly performs rollback/discard actions and later specifies `git reset --hard`, but the user-facing concept text does not prominently warn that uncommitted work can be destroyed. In an automated loop, silent destructive resets increase the chance of accidental data loss and unsafe operator assumptions.

Missing User Warnings

Medium
Confidence
80% confidence
Finding
The README advertises Telegram alerts as a safety feature without clearly warning that alert contents may be transmitted to a third-party service. In a monitoring system that may process prompts, commands, alerts, or security events, this can cause unintended disclosure of sensitive operational or user data to an external provider.

Missing User Warnings

Medium
Confidence
82% confidence
Finding
rollback() performs git reset --hard and git clean -fd, which irreversibly discards uncommitted and untracked data in the repository. In a self-improving autonomous agent loop, this becomes more dangerous because the operation may be triggered automatically and repeatedly without an explicit human confirmation boundary, increasing risk of accidental data loss.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This logger persistently writes sanitized tool-call arguments, agent identifiers, and session identifiers to disk in daily JSONL files without any visible consent, retention control, access restriction, or user-facing disclosure in this code path. In an autonomous agent loop, tool arguments can contain sensitive prompts, file paths, secrets, or user data, so durable local logging increases privacy and data-exposure risk even if some sanitization occurs.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The async review path sends formatted session entries to an arbitrary `agent_callable` without any consent, disclosure, redaction, or trust-boundary enforcement in this file. Session logs can contain prompts, file contents, secrets, commands, and other sensitive operational context, so this creates a real confidentiality risk if the callable is remote or third-party.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The logger appends arbitrary error text into the persistent TSV log with only tab/newline stripping. Error messages often contain sensitive local paths, tokens, command fragments, stack traces, prompts, or model outputs, so storing them verbatim can create unintended long-term disclosure to other local users, backups, or downstream tooling that consumes the log. In an autonomous self-improving agent loop, repeated failures can accumulate a substantial corpus of sensitive diagnostics, making this more dangerous than ordinary app logging.

Context Leakage

High
Category
Data Exfiltration
Content
session_entries: list[dict],
        agent_callable: AgentCallable,
    ) -> list[BehaviorHit]:
        """Send session to LLM for deep misalignment review."""

        # Build review prompt
        summary = self._format_session_for_review(session_entries)
Confidence
96% confidence
Finding
This is the same underlying issue: the code constructs a review prompt from session entries and hands it to `agent_callable` with no local-only guarantee. In an agent framework, session data often contains highly sensitive intermediate reasoning context, credentials, paths, and user data, making outbound review particularly risky.

Context Leakage

High
Category
Data Exfiltration
Content
session_entries: list[dict],
        agent_callable: AgentCallable,
    ) -> list[BehaviorHit]:
        """Send session to LLM for deep misalignment review."""

        # Build review prompt
        summary = self._format_session_for_review(session_entries)
Confidence
96% confidence
Finding
This is the same underlying issue: the code constructs a review prompt from session entries and hands it to `agent_callable` with no local-only guarantee. In an agent framework, session data often contains highly sensitive intermediate reasoning context, credentials, paths, and user data, making outbound review particularly risky.

Static analysis

No suspicious patterns detected.