Back to skill

Security audit

Gen Paylink Govilo

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but its file-packaging and setup instructions can expose users to unintended local file upload or unverified remote code execution.

Review before installing. Use Homebrew or another trusted package manager for uv instead of the curl/PowerShell installer commands, use a dedicated .env.govilo containing only the Govilo key and seller address, and upload only directories you created or have checked for symlinks. Avoid running this on untrusted repositories or extracted archives until symlink handling and temporary-file creation are fixed.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
references/setup-guide.md:8
Finding
Remote Installer Downloaded and Executed Without Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `references/setup-guide.md:8-13` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: High ### Vulnerable Code ```text ### Install uv # macOS / Linux curl -LsSf https://astral.sh/uv/install.sh | sh # Windows powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" ``` ### Technical Analysis The setup instructions pipe an HTTPS response directly into a shell on macOS/Linux and use `Invoke-Expression` to execute a downloaded PowerShell response on Windows. The downloaded payload is not pinned to a specific release and is not checked against a cryptographic hash or signature. Although `astral.sh` is presented as the official source for `uv`, the effective code executed by these commands can change after this Skill has been reviewed. Compromise of the upstream distribution service, DNS resolution, certificates, or the installer publication process could turn these commands into an arbitrary-code execution mechanism. The Windows command additionally bypasses the PowerShell execution policy for this invocation. These installation methods exceed the minimum privileges and trust required by the Skill: the Skill needs a Python runner, but it does not inherently require unreviewed network content to be executed directly. ### Attack Path 1. A user follows the installation instructions. 2. The shell retrieves the current response from the external installer URL. 3. The response is passed directly to `sh` or `iex` without being saved or inspected. 4. If the upstream service or delivery path has been compromised, attacker-controlled commands execute with the privileges of the invoking user. 5. The payload may read user-accessible secrets, alter files, install persistence, or download additional components. ### Impact Assessment Successful exploitation provides arbitrary command execution under the invoking user's account. The accessible scope ...[truncated 518 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `curl | sh` and `irm | iex` instructions. 2. Prefer installation through a trusted operating-system package manager, such as Homebrew or another platform-native package source. 3. If direct installation is necessary: - Pin a specific `uv` release. - Download the artifact to disk without executing it. - Obtain the expected checksum or signature through a separately authenticated channel. - Verify the artifact before installation. - Execute only the verified artifact. 4. Avoid bypassing PowerShell execution policy. 5. Document the required installer permissions and instruct users not to run installation commands as root or administrator unless strictly necessary. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/packager.py:40
Finding
Directory Packaging Follows Symbolic Links and Can Upload Files Outside the Selected Directory<![CDATA[ ## Vulnerability Details **File Location**: `scripts/packager.py:40-48` **Vulnerability Type**: Unintended local-file disclosure through symbolic-link traversal **Risk Level**: High ### Vulnerable Code ```python # Single directory — zip its contents if len(paths) == 1 and paths[0].is_dir(): files = [f for f in paths[0].rglob("*") if f.is_file()] if len(files) > MAX_FILE_COUNT: raise PackageError(f"Directory contains more than {MAX_FILE_COUNT} files") dest = Path(tempfile.mktemp(suffix=".zip")) with zipfile.ZipFile(dest, "w", zipfile.ZIP_DEFLATED) as zf: for f in files: zf.write(f, f.relative_to(paths[0])) ``` ### Technical Analysis `Path.is_file()` follows symbolic links. Consequently, a symbolic link located under the selected directory can be treated as a regular file even when its target is outside that directory. `ZipFile.write()` then opens and archives the target's contents, while `f.relative_to(paths[0])` only controls the archive member name; it does not prove that the resolved target remains inside the selected root. The resulting archive is subsequently uploaded to the presigned URL returned by Govilo. This behavior violates the expected boundary that selecting a directory should upload only files physically contained within that directory. ### Attack Path 1. An attacker or untrusted archive/repository creates a directory containing a symbolic link, for example `export/credentials`, pointing to a user-accessible sensitive file outside `export`. 2. The user invokes the Skill with `--input export`. 3. `rglob("*")` discovers the symbolic link and `is_file()` accepts it by following its target. 4. `ZipFile.write()` reads the external target and stores its contents under the link's relative archive name. 5. The workflow uploads the generated ZIP to the API-provided storage URL. 6. The sensitive contents become part of the paid Govilo item or otherwise enter remote storage. ### Impact Assessment ...[truncated 500 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Reject symbolic links explicitly before packaging: ```python if f.is_symlink(): raise PackageError(f"Symbolic links are not allowed: {f}") ``` 2. Resolve the selected root once and validate every candidate: ```python root = paths[0].resolve(strict=True) resolved = f.resolve(strict=True) if not resolved.is_relative_to(root): raise PackageError(f"Path escapes selected directory: {f}") ``` 3. Open files defensively where supported, using no-follow semantics to reduce time-of-check/time-of-use races. 4. Revalidate containment immediately before opening each file. 5. Add tests covering: - Symlinks to files outside the root. - Symlinks to files inside the root. - Broken symlinks. - Links changed concurrently during packaging. 6. Clearly document that only ordinary files within the selected root will be uploaded. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/packager.py:44
Finding
Predictable Non-Atomic Temporary Archive Creation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/packager.py:44-48, 54-56` **Vulnerability Type**: Insecure temporary-file creation **Risk Level**: Medium ### Vulnerable Code ```python dest = Path(tempfile.mktemp(suffix=".zip")) with zipfile.ZipFile(dest, "w", zipfile.ZIP_DEFLATED) as zf: for f in files: zf.write(f, f.relative_to(paths[0])) _validate_zip(dest) return dest ``` The same pattern is used for multiple inputs: ```python dest = Path(tempfile.mktemp(suffix=".zip")) _zip_paths(paths, dest) _validate_zip(dest) return dest ``` ### Technical Analysis `tempfile.mktemp()` generates a candidate pathname but does not atomically create and reserve the file. A local process can create a file or symbolic link at that pathname between name generation and the call that opens the ZIP. This is a time-of-check/time-of-use race in a generally shared temporary directory. Depending on platform behavior and permissions, an attacker may redirect writes to another user-writable target, interfere with the generated archive, or replace the archive before it is validated or uploaded. ### Attack Path 1. The Skill calls `tempfile.mktemp()` and receives an unused pathname. 2. A local attacker observes, predicts, or races to occupy that path. 3. The attacker creates a symbolic link or malicious file at the selected path before `ZipFile` opens it. 4. Archive creation follows or overwrites the attacker-controlled path where platform semantics permit it. 5. Alternatively, the attacker replaces the temporary archive after creation but before validation or upload. 6. The workflow may overwrite an unintended target or upload attacker-modified content. ### Impact Assessment Exploitation requires local access and the ability to interact with the temporary directory. Potential consequences include: - Modification or overwrite of files writable by the invoking user. - Manipulation of the archive uploaded to Govilo. - Disclosure of packaged data to anot ...[truncated 212 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `tempfile.mktemp()` with an API that atomically creates the file: - `tempfile.NamedTemporaryFile(delete=False, suffix=".zip")`, or - `tempfile.mkstemp(suffix=".zip")`. 2. Retain and safely manage the returned file descriptor rather than closing it and reopening an untrusted pathname where possible. 3. Ensure restrictive file permissions are applied at creation. 4. Keep the temporary file open through creation and upload where practical. 5. Validate that the temporary path still refers to the originally created regular file before upload. 6. Preserve the existing `finally` cleanup behavior, and add cleanup for errors occurring during archive construction. ]]>

T08 · Insecure Dependencies

Warning
Location
pyproject.toml:5
Finding
Unpinned Runtime and Build Dependencies Allow Non-Reproducible Code Resolution<![CDATA[ ## Vulnerability Details **File Location**: `pyproject.toml:5, 12-13` **Vulnerability Type**: Unpinned third-party dependencies **Risk Level**: Medium ### Vulnerable Code ```toml dependencies = ["requests"] ``` ```toml [build-system] requires = ["hatchling"] build-backend = "hatchling.build" ``` The setup guide confirms that dependencies are resolved automatically: ```text `uv run` automatically resolves Python >=3.11 and the `requests` dependency from `pyproject.toml` — no manual `pip install` needed. ``` ### Technical Analysis The runtime dependency `requests` and build dependency `hatchling` have no version constraints. No lock file was present in the audited project structure. Each environment may therefore resolve different package versions, and future upstream releases can become part of the executed environment without a corresponding Skill review. Build-system dependencies are particularly security-sensitive because they may execute during package construction or installation. This finding does not establish that either named package is currently malicious; it identifies a supply-chain control deficiency and lack of reproducibility. ### Attack Path 1. A user runs the documented `uv run` command in an environment without a trusted lock file. 2. The resolver selects versions available from its configured package index at that time. 3. A compromised upstream release, compromised package index, or unsafe future version is downloaded. 4. Build or runtime package code executes with the user's privileges. 5. Malicious dependency code could read local data, alter files, or intercept the Govilo API key and uploaded content. ### Impact Assessment If dependency distribution is compromised, package code executes with the same privileges as the Skill. Accessible scope may include: - `GOVILO_API_KEY` and `SELLER_ADDRESS` from the process environment. - Files selected for packaging and upload. - Other files readable or writable by the invoking ...[truncated 253 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Constrain runtime and build dependency versions to reviewed releases. 2. Generate and commit a `uv.lock` file or equivalent reproducible dependency lock. 3. Use hash verification for downloaded distributions where supported. 4. Ensure deployment and documented execution commands enforce use of the lock file. 5. Review transitive dependencies and update them through a controlled process. 6. Configure trusted package indexes explicitly in controlled environments. 7. Run dependency vulnerability and provenance checks as part of release validation. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill advertises sensitive remote behavior involving file uploads, presigned URLs, API-key usage, and monetization workflows, but the analyzed content does not substantiate those actions and instead appears centered on local packaging/validation. This mismatch is dangerous because users and reviewers may authorize secret access and file handling under false assumptions, masking dead code, incomplete implementation, or substituted behavior in other files.

Context Leakage

High
Category
Data Exfiltration
Content
| 809108003 | 401 | api key has expired |
| 809108005 | 429 | daily api key usage limit exceeded |
| 809108006 | 429 | api key rate limit exceeded |
| 809104001 | 404 | upload session not found |
| 809104002 | 410 | upload session expired |
| 809104003 | 404 | file not found |
Confidence
85% confidence
Finding
Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Context Leakage

High
Category
Data Exfiltration
Content
| 809108003 | 401 | api key has expired |
| 809108005 | 429 | daily api key usage limit exceeded |
| 809108006 | 429 | api key rate limit exceeded |
| 809104001 | 404 | upload session not found |
| 809104002 | 410 | upload session expired |
| 809104003 | 404 | file not found |
Confidence
85% confidence
Finding
Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Chaining Abuse

High
Category
Tool Misuse
Content
### Install uv

    # macOS / Linux
    curl -LsSf https://astral.sh/uv/install.sh | sh

    # Windows
    powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Confidence
96% confidence
Finding
The `| sh` shell-chaining pattern is a direct arbitrary-command execution sink for whatever data is returned by the remote endpoint. If an attacker can influence the downloaded content or the transport path, they can execute malicious commands immediately, potentially stealing Govilo API keys, wallet-related data, or other local secrets used by this skill.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill explicitly requires environment variables and describes network-based upload/API operations, but it does not declare any tool scope such as permissions or allowed-tools. That creates an authorization gap where the runtime may permit broader env or network access than reviewers and users expect, increasing the chance of secret exposure or unintended outbound requests.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The reference explicitly documents authenticated API calls and raw ZIP uploads to an external Govilo service, but provides no warning that user files and metadata will be transmitted off-platform. In the context of an agent skill that automates uploads, this omission increases the risk of users or downstream agents sending sensitive data to a third party without informed consent.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The setup guide instructs users to execute installer scripts fetched directly from the internet without any warning or verification step. Even if the upstream source is legitimate, this pattern creates a supply-chain risk: a compromised host, CDN, DNS path, or installer script could lead to arbitrary code execution on the user's machine.

External Transmission

Medium
Category
Data Exfiltration
Content
return body["data"]

    def presign(self, seller_address: str) -> dict:
        resp = requests.post(
            f"{self._base_url}/api/v1/bot/uploads/presign",
            headers=self._headers,
            json={"seller_address": seller_address},
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The presign method sends the user-provided seller_address to a remote API via requests.post, but the file contains no confirmation prompt, logging, or explanatory comment disclosing that this data is transmitted externally. Because this is a code file, outbound transmission of user or system data should have some visible disclosure unless clearly covered elsewhere in the skill description.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The upload method reads a local zip file and transmits its contents to upload_url using an HTTP PUT request. There is no confirmation prompt, user-facing log, or inline documentation warning that local file contents will be sent off-system, which is a safety-relevant operation for code files.

External Transmission

Medium
Category
Data Exfiltration
Content
price: str,
        description: str = "",
    ) -> dict:
        resp = requests.post(
            f"{self._base_url}/api/v1/bot/items",
            headers=self._headers,
            json={
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding
The project declares `requests` without any version constraint, so dependency resolution may install a release affected by known vulnerabilities. In this skill's context, `requests` is likely used for Govilo API calls and presigned upload flows, so a vulnerable or unexpectedly changed HTTP client could expose credentials, mishandle redirects/auth, or introduce supply-chain instability in a network-facing workflow.

Unverifiable Dependency: pytest has 2 known advisory(ies) (CVE-2025-71176 (pytest has vulnerable tmpdir handling); CVE-2025-71176 (pytest has vulnerable tmpdir handling)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

External Script Fetching

Low
Category
Supply Chain
Content
### Install uv

    # macOS / Linux
    curl -LsSf https://astral.sh/uv/install.sh | sh

    # Windows
    powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Confidence
95% confidence
Finding
The command `curl ... | sh` fetches a remote script and immediately executes it, giving that remote content full code execution privileges in the user's shell. In a setup guide for a developer tool, this is more dangerous because users are likely to run it verbatim, often in trusted local environments that may contain credentials or source code.

Static analysis

No suspicious patterns detected.