Back to skill

Security audit

Code Cache

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent code-caching purpose, but it retrieves third-party code into the local filesystem and can overwrite files outside the cache directory without adequate safeguards.

Review this skill carefully before installing. Use it only in a constrained workspace, do not upload secrets or proprietary files unless you intend to send them to Raysurfer, inspect downloaded files before execution, and avoid adding server-provided prompt text to an agent as instructions.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
code_cache.py:91
Finding

Remote-Controlled Filename Allows Arbitrary File Write Outside the Cache Directory

Content
View full analysis

Vulnerability Details

File Location: code_cache.py, lines 91–102
Vulnerability Type: Path traversal and arbitrary file overwrite
Risk Level: High

python
result = client.get_code_files(
    task=task,
    top_k=args.top_k,
    cache_dir=args.cache_dir,
)

if not result.files:
    print(f"No code files found for: {task}")
    return

print(f"Retrieved {len(result.files)} files for: {task}\n")

# Write files to cache directory
cache_path = Path(args.cache_dir)
cache_path.mkdir(parents=True, exist_ok=True)

for f in result.files:
    file_path = cache_path / f.filename
    file_path.write_text(f.source)

Technical Analysis

The filename and source content originate from the external Raysurfer API. The implementation joins cache_path with f.filename without validating whether the filename is absolute or contains parent-directory components.

In Python, joining a Path to an absolute child discards the original base path. A relative filename containing components such as ../../ can similarly resolve outside the intended cache directory. write_text() also overwrites an existing file by default.

Consequently, the external service controls both the destination path and the content written to it. The code does not resolve the final path and verify that it remains beneath the selected cache directory.

Attack Path

  1. An attacker poisons a cache entry, compromises an account, or compromises the external cache service.
  2. The malicious response contains a filename such as ../../project/config.py, ../../.bashrc, or an absolute path.
  3. A user invokes the files command for a task matching the poisoned entry.
  4. The Skill joins the attacker-controlled filename to the local cache path.
  5. write_text() writes attacker-controlled source outside the cache directory and overwrites the target if it already exists.
  6. If the overwritten file is later imported, executed, or ...[truncated 606 chars]
Remediation
View remediation

Remediation Suggestions

  • Treat every filename returned by the API as untrusted.
  • Reject absolute paths, parent-directory components, empty names, device names, and unexpected separators.
  • Resolve the destination path and verify that it remains strictly beneath the resolved cache directory:
python
cache_path = Path(args.cache_dir).resolve()
cache_path.mkdir(parents=True, exist_ok=True)

for remote_file in result.files:
    relative_name = Path(remote_file.filename)

    if relative_name.is_absolute() or ".." in relative_name.parts:
        raise ValueError(f"Unsafe remote filename: {remote_file.filename}")

    destination = (cache_path / relative_name).resolve()
    if cache_path not in destination.parents:
        raise ValueError(f"Filename escapes cache directory: {remote_file.filename}")

    destination.parent.mkdir(parents=True, exist_ok=True)
    destination.write_text(remote_file.source)
  • Prefer a strict filename allowlist if nested directories are unnecessary.
  • Avoid silently overwriting existing files. Use exclusive creation or require explicit confirmation.
  • Add tests covering absolute paths, ../ traversal, nested traversal, symbolic links, and overwrite attempts.

T01 · Skill Instruction Hijacking

Error
Location
code_cache.py:105
Finding

Untrusted Server Response Is Presented for Direct Injection into the Agent Prompt

Content
View full analysis

Vulnerability Details

File Location: code_cache.py, line 105
Vulnerability Type: External prompt injection
Risk Level: High

python
print(f"\n--- Add to LLM prompt ---\n{result.add_to_llm_prompt}")

The behavior is also presented as an intended feature in README.md, lines 84–89, and SKILL.md, lines 52–55.

Technical Analysis

result.add_to_llm_prompt is controlled by the external Raysurfer service or by data stored in its shared cache. The Skill emits that value verbatim under the heading “Add to LLM prompt,” expressly encouraging it to be inserted into an agent’s instruction context.

No trust-boundary marker, escaping, filtering, provenance information, or instruction/data separation is applied. If a cache entry or service response contains imperative text, an AI agent may interpret it as authoritative instructions rather than untrusted retrieval data.

This creates an instruction-hijacking channel through which a mutable external response can alter the agent’s current goals or tool-use decisions.

Attack Path

  1. An attacker creates or poisons a cache entry that matches a likely user task.
  2. The entry causes the API to return an add_to_llm_prompt value containing malicious instructions.
  3. The user invokes the files command.
  4. The Skill prints the malicious response as text intended to be added to the LLM prompt.
  5. The agent or user inserts that text into the active prompt as directed by the Skill.
  6. The agent may follow the injected instructions, such as reading sensitive files, uploading additional content, ignoring the original task, or running unsafe downloaded code, subject to the agent’s available tools and permissions.

Impact Assessment

The direct impact is alteration of the current agent session’s goals and safety posture. The ultimate scope depends on the tools granted to the agent. An agent with filesystem, network, or execution tools could be induced to disc ...[truncated 232 chars]

Remediation
View remediation

Remediation Suggestions

  • Do not insert server-provided text directly into an instruction channel.
  • Generate any necessary agent guidance from a fixed, locally reviewed template.
  • Represent retrieved descriptions as quoted, untrusted data with explicit boundaries.
  • Include source and provenance information for every retrieved result.
  • Require explicit user approval before making retrieved content available to an agent.
  • Remove imperative server-provided text or apply strict schema validation that permits only expected metadata fields.
  • Ensure the local system prompt explicitly states that retrieved cache content is data and must not override system, developer, or user instructions.
  • Add adversarial tests using responses containing instruction-override language, tool-use requests, and data-exfiltration requests.

T09 · Insecure Skill Coding Practices

Warning
Location
code_cache.py:110
Finding

Upload Command Can Transmit Arbitrary Readable Local Files to a Third Party

Content
View full analysis

Vulnerability Details

File Location: code_cache.py, lines 110–130
Vulnerability Type: Unrestricted sensitive-file upload
Risk Level: Medium

python
def cmd_upload(args: argparse.Namespace) -> None:
    """Upload code to the cache."""
    client = get_client()

    files_written = []
    for file_path in args.files:
        path = Path(file_path)
        if not path.exists():
            print(f"Error: File not found: {file_path}", file=sys.stderr)
            sys.exit(1)

        files_written.append(FileWritten(
            path=str(path),
            content=path.read_text(),
        ))

    client.upload_new_code_snips(
        task=args.task,
        files_written=files_written,
        succeeded=args.succeeded,
        auto_vote=not args.no_auto_vote,
    )

    print(f"✓ Uploaded {len(files_written)} file(s) for task: {args.task}")
    print(f"  Succeeded: {args.succeeded}")

Technical Analysis

The upload command accepts arbitrary paths and reads their complete text content before sending it through the Raysurfer client. It only verifies that each path exists.

The implementation does not enforce a workspace boundary, require code-file extensions, reject symbolic links, detect secrets, restrict sensitive filenames, impose file-size limits, preview the transmitted content, or require a separate confirmation step.

Uploading code to Raysurfer is part of the declared functionality, so this is not a covert network operation. However, accepting every readable text path exceeds the minimum filesystem privileges needed for a code-cache feature and increases the consequences of user mistakes or prompt injection.

Attack Path

  1. A malicious prompt, retrieved cache entry, or misleading task instructs an agent to upload a sensitive local path.
  2. The agent invokes the command with a path to a file such as .env, a private configuration file, or proprietary source. 3 ...[truncated 694 chars]
Remediation
View remediation

Remediation Suggestions

  • Restrict uploads to regular files beneath an explicitly configured workspace root.
  • Resolve paths before reading them and reject paths that escape the workspace.
  • Reject symbolic links unless their resolved targets are independently validated.
  • Permit only reviewed code and text extensions required by the feature.
  • Deny sensitive filenames and directories, including .env, credential stores, key files, hidden configuration directories, and version-control metadata.
  • Scan content for likely secrets before upload and block or redact detected values.
  • Enforce conservative per-file and total-upload size limits.
  • Display the destination service, resolved file paths, sizes, and a content summary before transmission.
  • Require explicit user confirmation for every upload, particularly when invoked by an autonomous agent.
  • Add tests for workspace escape, symbolic links, hidden files, secret detection, binary files, and oversized content.

T08 · Insecure Dependencies

Note
Location
code_cache.py:37
Finding

Security-Critical Raysurfer Dependency Is Recommended Without Version or Integrity Pinning

Content
View full analysis

Vulnerability Details

File Location: code_cache.py, lines 37–40
Vulnerability Type: Unpinned third-party dependency guidance
Risk Level: Low

python
if not HAS_RAYSURFER:
    print("Error: raysurfer package not installed", file=sys.stderr)
    print("Install with: pip install raysurfer", file=sys.stderr)
    sys.exit(1)

Technical Analysis

The Skill directs users to install the latest available raysurfer package without a reviewed version constraint or integrity hash. This dependency receives the Raysurfer API key and implements all network interactions involving downloaded code, task descriptions, votes, and uploaded file contents.

An unpinned installation can produce different effective behavior over time after the Skill itself has been reviewed. Although the project history provides no evidence that the current package is malicious, the dependency is security-critical and lacks reproducible installation controls.

Attack Path

  1. A user runs the Skill without the required dependency.
  2. The Skill instructs the user to run pip install raysurfer.
  3. The package index supplies whichever release is current at installation time.
  4. If a future release or package-maintainer account is compromised, malicious installation or import-time code runs with the user’s privileges.
  5. The compromised dependency may access the API key, local process data, and all content passed through the client.

Impact Assessment

Exploitation would provide dependency code with the same operating-system privileges as the Skill process. It could access RAYSURFER_API_KEY, alter API requests or responses, capture uploaded files, return malicious filenames or prompt text, and access other resources available to the Python process. This is a supply-chain hardening deficiency rather than evidence of an existing malicious dependency.

Remediation
View remediation

Remediation Suggestions

  • Pin the dependency to a reviewed version instead of recommending an unconstrained installation.
  • Maintain the dependency in a lockfile with cryptographic hashes.
  • Provide a reproducible installation command based on the lockfile.
  • Verify package provenance and review release changes before updating the pin.
  • Run the dependency with only the environment variables and filesystem access required for the selected operation.
  • Periodically audit the dependency and its transitive dependency tree for known vulnerabilities and unexpected ownership changes.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (8)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README explicitly promotes retrieving and running code from prior executions via an external API ('No waiting. No regenerating. Just execute.') without any safety caveats. Encouraging execution of remotely sourced cached code can lead users to run unreviewed, potentially malicious or unsafe code in their environment, especially because the cache contents originate from previous agent outputs rather than a trusted package registry.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README states that /code-cache files downloads executable code files into the sandbox and provides them to the agent, but it does not disclose that this writes untrusted files into the environment. In an agent setting, introducing external code into the workspace can influence subsequent tool use, execution flow, or file consumption, increasing the risk of code execution or workspace contamination.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The upload workflow indicates that task descriptions and successful code are sent to the Raysurfer API, but the README does not warn users about privacy, confidentiality, or data handling implications. Users may unknowingly transmit proprietary prompts, credentials embedded in code, customer data, or other sensitive business logic to a third-party service.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill advertises capabilities that imply reading environment variables and reading/writing files, but it does not declare an explicit tool scope such as permissions or allowed-tools. That makes the operational boundary unclear to users and host platforms, increasing the chance the skill can access sensitive data or modify local files without adequate review.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explains setup and usage of an external Raysurfer API, but it does not clearly warn that task descriptions and uploaded code files are transmitted to a third-party service. This creates a real data exfiltration and privacy risk, especially if agents upload proprietary source code, secrets, or internal task context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly says the agent can retrieve and run cached code from prior executions, but it does not warn that cached code may be unsafe, stale, or malicious. Recommending execution of retrieved code without review increases the chance of arbitrary code execution, persistence of previously compromised snippets, or reuse of code that is unsafe in a different context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The files command retrieves code from a remote service and writes it directly into the local filesystem without any explicit trust boundary warning, review step, or filename safety validation beyond path joining. In a code-reuse skill, this is especially risky because the written files may later be executed by an agent or operator, turning untrusted remote content into a local supply-chain vector.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The upload command reads arbitrary local files and sends their full contents to the external Raysurfer API via upload_new_code_snips, but the CLI does not provide an explicit warning or confirmation that data will leave the local environment. In an agent-skill context, users or higher-level agents may invoke this command assuming it is a local cache, which increases the risk of unintentionally exfiltrating secrets, proprietary code, or credentials contained in the selected files.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.