Back to skill

Security audit

Agent Guru

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent production-agent design guide, but several examples teach high-impact agent features with unsafe or under-scoped defaults.

Review this skill carefully before installing or using it as implementation guidance. It is not trying to hide executable malware, but do not copy the production examples verbatim: add workspace-bounded file writes, deny-overrides-allow permission precedence, explicit user and tenant checks for sessions, redaction and retention controls for telemetry, opt-in memory loading, secret-managed database credentials, dependency pinning, and cost/runtime limits.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (7)

T01 · Skill Instruction Hijacking

Error
Location
references/memory-layer.md:121
Finding

Untrusted project memory files are injected into the system prompt

Content
View full analysis
str: """Discover and load persistent memory files from known locations.""" memory_content = [] for directory in search_dirs: for filename in ["AGENT.md", "MEMORY.md", ".agent-context.md"]: path = Path(directory) / filename if path.exists(): memory_content.append(f"# From {path}\n{path.read_text()}") return "\n\n---\n\n".join(memory_content) def build_system_prompt(base_prompt: str, working_dir: str) -> str: memory = load_memory_files([ working_dir, os.path.expanduser("~/.agent"), "/etc/agent/global" ]) if memory: return f"{base_prompt}\n\n## Project Context (always apply)\n\n{memory}" return base_prompt ``` ### Technical Analysis The implementation reads instruction-like files from the working directory, the current user's home directory, and a global configuration directory without validating their ownership, integrity, provenance, or content. Their contents are then appended to the system prompt under the authoritative phrase `always apply`. A repository contributor can place a malicious `AGENT.md`, `MEMORY.md`, or `.agent-context.md` in a project. When an agent operates in that directory, attacker-controlled text receives system-prompt-level influence. If the agent has tools, these instructions can attempt to induce file modification, secret access, network requests, or other actions unrelated to the user's legitimate task. Although this is presented as an example rather than an automatically executed package script, copying it into an agent harness creates a persistent prompt-injection boundary. ### Attack Path 1. An attacker adds a m ...[truncated 858 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
references/tool-safety-layer.md:70
Finding

First-match permission rules allow production protection bypasses

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
references/tool-safety-layer.md:31
Finding

Write tool permits unrestricted absolute-path file overwrite

Content
View full analysis
str: """Write content to a file. Creates or overwrites the file at the given path.""" import os if create_dirs: os.makedirs(os.path.dirname(path), exist_ok=True) with open(path, "w") as f: f.write(content) return f"Successfully wrote {len(content)} characters to {path}" ``` ### Technical Analysis The tool explicitly accepts arbitrary absolute paths and overwrites the selected file. It enforces no workspace boundary, path allowlist, file-type restriction, symlink protection, ownership validation, or human approval. The optional directory creation expands the writable scope further. Schema validation only verifies data types; it does not create an authorization boundary. If a model is manipulated through prompt injection or an incorrect plan, the tool can modify any path writable by the host process. ### Attack Path 1. An attacker supplies content that induces the agent to call `write_file`. 2. The call specifies a sensitive writable path, such as an application configuration file, shell startup file, credential file, or deployed source file. 3. If needed, `create_dirs=True` creates missing parent directories. 4. `open(path, "w")` truncates and replaces the target. 5. The altered file changes application behavior, destroys data, or provides a later execution opportunity. ### Impact Assess ...[truncated 302 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
references/observability-layer.md:32
Finding

Telemetry logs potentially sensitive prompts, tool inputs, and outputs without redaction

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
references/persistence-layer.md:64
Finding

Session resume and fork operations do not enforce user ownership

Content
View full analysis
dict: """Resume an existing session — LangGraph loads checkpoint automatically.""" config = {"configurable": {"thread_id": session_id}} return app.invoke( {"messages": [HumanMessage(new_message)]}, config=config ) # Start a session session = create_session("user-123", "refactor the auth module") result = app.invoke( {"messages": [HumanMessage(session["task"])]}, config={"configurable": {"thread_id": session["session_id"]}} ) # Resume later — picks up exactly where it left off result = resume_session(app, session["session_id"], "also add rate limiting") def fork_session(app, parent_session_id: str) -> str: """Fork a session from its current state into a new independent session.""" parent_state = app.get_state( config={"configurable": {"thread_id": parent_session_id}} ) fork_id = str(uuid.uuid4()) app.update_state( config={"configurable": {"thread_id": fork_id}}, values=parent_state.values ) return fork_id ``` ### Technical Analysis Both operations use possession of a session identifier as the only access condition. They do not accept an authenticated user or tenant identity and do not verify that the requested session belongs to the caller. UUIDs reduce random guessing but are identifiers, not authorization credentials. They can leak through telemetry, URLs, browser history, support tickets, or application logs. Once disclosed, the identifier can be used to resume or clone the associated checkpoint. ### Attack Path 1. An attacker obtains another user's session or thread identifier from logs, telemetry, a URL, or an accidental disclosure. 2. The attacker passes the identifier ...[truncated 610 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
references/persistence-layer.md:43
Finding

Production database example embeds plaintext credentials in the connection URI

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
references/persistence-layer.md:8
Finding

Dependency installation instructions use mutable, unpinned package versions

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (13)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/tool-safety-layer.md (reported line 23)May include surrounding context.

LOW RISK (always-allow): read_file, list_dir, search, get_status MEDIUM RISK (auto-approve): write_file, create_record, send_notification HIGH RISK (human-in-loop): delete_*, drop_table, deploy, apply_migration ALWAYS DENY: rm -rf /, DROP DATABASE, force_push_main

text

## Tool Definition with Schema

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/tool-safety-layer.md (reported line 23)May include surrounding context.

LOW RISK (always-allow): read_file, list_dir, search, get_status MEDIUM RISK (auto-approve): write_file, create_record, send_notification HIGH RISK (human-in-loop): delete_*, drop_table, deploy, apply_migration ALWAYS DENY: rm -rf /, DROP DATABASE, force_push_main

text

## Tool Definition with Schema

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/tool-safety-layer.md (reported line 23)May include surrounding context.

LOW RISK (always-allow): read_file, list_dir, search, get_status MEDIUM RISK (auto-approve): write_file, create_record, send_notification HIGH RISK (human-in-loop): delete_*, drop_table, deploy, apply_migration ALWAYS DENY: rm -rf /, DROP DATABASE, force_push_main

text

## Tool Definition with Schema

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · references/tool-safety-layer.md (reported line 91)May include surrounding context.

md
def _check_permission(self, tool_name: str, args: dict):
        for rule in self.rules:
            if rule.matches(tool_name, args):
                return rule.mode, rule.reason
        return PermissionMode.ASK, "no matching rule — defaulting to ask"

    def __call__(self, state):

Context Window Stuffing

Medium
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Content

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

md
- **Never dump the full parent message history into a subagent.** Pass only the specific task and relevant data — context pollution degrades performance and wastes tokens.
- **`InMemorySaver` is for development only.** Use Redis or Postgres checkpointers in production.
- **`interrupt()` pauses the graph.** Resume it by calling `graph.invoke(Command(resume=...), config=config)` — forgetting this leaves the agent stuck.
- **Tool result truncation is mandatory.** Large tool outputs (file reads, search results) will exhaust the context window if not truncated before returning.
- **Always set `max_iterations`.** Without a loop guard, a miscalibrated agent runs indefinitely and incurs unbounded cost.
- **Apply compaction in tiers.** Budget tool results → snip → microcompact → autocompact. Jumping straight to full summarization wastes tokens when a cheaper step would suffice.
- **Track diminishing returns, not just token budget.** An agent can burn through its iteration budget producing nearly empty continuations. Stop when the last 2 deltas are both below ~500 tokens.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The document recommends automatically loading and injecting persistent memory files from project, user-home, and global locations into every system prompt without requiring explicit user notice, consent, or retention guidance. In a production multi-agent design context, this can cause sensitive project data, secrets, or personal information to be silently propagated into model prompts and downstream providers, creating privacy, compliance, and unintended data-exposure risks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The long-term memory design stores arbitrary content in a persistent vector store and later recalls it for prompt injection, but the guidance only briefly mentions PII controls in a mistakes table and does not make sensitive-data handling a hard requirement. This is dangerous because agents may store user prompts, findings, credentials, regulated data, or business secrets in durable storage, where they can be retained longer than intended, retrieved across tasks, or exposed through weak filtering and access controls.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The observability guidance explicitly recommends capturing LLM reasoning steps, tool inputs/outputs, and prompt previews, and the sample callback emits that content to a sink by default. In a production multi-agent setting, those fields can contain credentials, proprietary data, PII, or sensitive user prompts, creating a real data-exposure risk if logs are retained broadly or sent to third-party observability platforms.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The example creates both a session_id and a distinct thread_id, but the run/resume paths actually use session_id as the LangGraph checkpoint key. This inconsistency can cause developers to persist or authorize against one identifier while loading state from another, leading to broken session isolation, incorrect resumption, or accidental cross-user access if the mapping logic is implemented incorrectly.

Content

No source excerpt is available for this finding.

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · references/resilience-layer.md (reported line 295)May include surrounding context.

md
is_unattended: bool = False,
) -> AsyncGenerator:
    """
    Retry indefinitely with exponential backoff + keep-alive heartbeats.
    Use only for truly unattended contexts — not interactive sessions.
    """
    if not is_unattended:

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The document makes an absolute safety claim ('your agent is safe regardless of what the LLM decides to do') while later introducing a remote policy-controlled bypass capability. Even though the sample kill-switch fails safe on fetch error, any bypass mode that can weaken local controls undermines the earlier guarantee and can lead operators to overtrust the system.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · references/tool-safety-layer.md (reported line 21)May include surrounding context.

text
LOW RISK   (always-allow):   read_file, list_dir, search, get_status
MEDIUM RISK (auto-approve):  write_file, create_record, send_notification
HIGH RISK  (human-in-loop):  delete_*, drop_table, deploy, apply_migration
ALWAYS DENY:                  rm -rf /, DROP DATABASE, force_push_main

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The markdown recommends capturing environment state at query start and includes code that reads values from environment variables. While the sample variables are not credentials, the surrounding guidance to snapshot environment state is broad and could lead implementers to capture sensitive configuration or secrets without any cautionary note.

Content

No source excerpt is available for this finding.