Back to skill

Security audit

Fold

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its FastFold job-management purpose, but its scripts can send a saved FastFold API key to arbitrary HTTP or HTTPS endpoints.

Install only if you are comfortable with a FastFold helper that reads FASTFOLD_API_KEY from local environment files and makes authenticated API calls. Do not use --base-url with anything except a trusted FastFold endpoint, avoid plaintext HTTP, review any public-job setting before submitting proprietary sequences, and keep .env out of version control.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/security_utils.py:23
Finding

FastFold API key can be disclosed to an arbitrary user-selected endpoint

Content
View full analysis

Vulnerability Details

File Location: scripts/security_utils.py:23-35, with the unsafe value consumed by authenticated requests in scripts/create_job.py:78-89, scripts/download_cif.py:32-37, scripts/fetch_results.py:24-29, scripts/get_viewer_link.py:28-33, and scripts/wait_for_completion.py:25-30
Vulnerability Type: Arbitrary credential destination and plaintext bearer-token transmission
Risk Level: High

Vulnerable Code

python
def validate_base_url(base_url: str) -> str:
    """Basic safety checks for API base URL."""
    parsed = urlparse(base_url)
    if parsed.scheme not in ("https", "http"):
        sys.exit("Error: base URL must use http or https.")
    if not parsed.netloc:
        sys.exit("Error: base URL must include a host.")
    if parsed.username or parsed.password:
        sys.exit("Error: base URL must not include credentials.")
    if parsed.query or parsed.fragment:
        sys.exit("Error: base URL must not include query or fragment.")
    return f"{parsed.scheme}://{parsed.netloc}{parsed.path}".rstrip("/")

The validated value is then used for authenticated requests. For example, scripts/create_job.py:78-89 contains:

python
url = f"{base_url.rstrip('/')}/v1/jobs"
if from_id:
    url = f"{url}?from={from_id}"
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
req = urllib.request.Request(
    url=url,
    data=json.dumps(body).encode("utf-8"),
    headers=headers,
    method="POST",
)
try:
    with urllib.request.urlopen(req, timeout=30) as resp:
        response_text = resp.read().decode("utf-8", errors="replace")
        status = resp.getcode()

Technical Analysis

All authenticated scripts expose a --base-url argument. The shared validate_base_url() function accepts any host and permits both HTTPS and plaintext HTTP. The scripts subsequently attach the value of FASTFOLD_API_KEY ...[truncated 2381 chars]

Remediation
View remediation

Remediation Suggestions

  1. Require HTTPS for every authenticated API request. Remove support for plaintext HTTP.
  2. Allowlist api.fastfold.ai as the default and only permitted host for production credentials.
  3. If alternate deployments are genuinely required, separate their credentials from FASTFOLD_API_KEY and require explicit trusted-host configuration rather than accepting an unrestricted CLI URL.
  4. Disable automatic redirects for authenticated requests, or validate every redirect destination before following it. Never preserve the authorization header across a host change.
  5. Reject IP literals, embedded user information, unexpected ports, and non-allowlisted subdomains unless specifically required and approved.
  6. Update references/auth_and_api.md to state that production FastFold credentials must never be sent to alternate endpoints.
  7. Add regression tests proving that HTTP URLs, attacker-controlled domains, deceptive subdomains, and cross-host redirects are rejected.

A strict production validator could use the following policy:

python
def validate_base_url(base_url: str) -> str:
    parsed = urlparse(base_url)
    if parsed.scheme != "https":
        sys.exit("Error: API base URL must use HTTPS.")
    if parsed.hostname != "api.fastfold.ai":
        sys.exit("Error: authenticated API host is not trusted.")
    if parsed.username or parsed.password:
        sys.exit("Error: base URL must not include credentials.")
    if parsed.port not in (None, 443):
        sys.exit("Error: unexpected API port.")
    if parsed.query or parsed.fragment:
        sys.exit("Error: base URL must not include query or fragment.")
    return "https://api.fastfold.ai"
Vulnerability Patterns
  • 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
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a comprehensive FastFold job-management capability, covering submission, polling, completion handling, and retrieval of multiple result types. The supplied code chunk only implements one post-processing step: given an existing completed job ID, retrieve the results payload and download CIF artifacts. This is a materially narrower purpose than the declaration. While authentication and Jobs API access are consistent with the domain, major declared capabilities are absent, and the code additionally performs local file downloads/writes that are not called out in the description. Therefore the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description claims a comprehensive FastFold Jobs API integration covering authentication, creating jobs, polling until completion, and retrieving structural result links and metrics. The actual code chunk is much narrower: it accepts a job ID, optionally verifies the job via GET /v1/jobs/{job_id}/results using FASTFOLD_API_KEY, and prints a preformatted cloud viewer URL. While viewer-link retrieval is consistent with part of the description, the primary behavior of this specific code chunk does not match the broad declared functionality. This is a material scope mismatch because major declared capabilities are absent from the supplied code.

Content

No source excerpt is available for this finding.

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · references/jobs.yaml (reported line 14)May include surrounding context.

yaml
openapi: 3.1.1
info:
  title: FastFold Jobs API
  version: 1.0.0
  contact:
    name: FastFold API Support
    email: hello@fastfold.ai
  license:
    name: Proprietary
    url: https://fastfold.ai

servers:
  - url: https://api.fastfold.ai
    description: Production server

security:
  - bearerAuth: []

tags:
  - name: Jobs
    description: Create and manage jobs

paths:
  '/v1/jobs':
    post:
      tags:
        - Jobs
      summary: Create Job
      description: |
        Create a new job to fold protein sequences using AI models. The job will be processed
        asynchronously and you can track its status using the returned job ID.

      operationId: createJob
      parameters:
        - name: from
          in: query
          description: Optional library item ID to associate with this job
          required: false

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/create_job.py (reported line 31)May include surrounding context.

python
"""
Load FASTFOLD_API_KEY (and other vars) from a .env file so scripts work without
exporting the key in the shell. Searches current directory and parent directories
for .env; only sets variables that are not already in os.environ.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/create_job.py (reported line 146)May include surrounding context.

python
"""
Load FASTFOLD_API_KEY (and other vars) from a .env file so scripts work without
exporting the key in the shell. Searches current directory and parent directories
for .env; only sets variables that are not already in os.environ.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/download_cif.py (reported line 115)May include surrounding context.

python
"""
Load FASTFOLD_API_KEY (and other vars) from a .env file so scripts work without
exporting the key in the shell. Searches current directory and parent directories
for .env; only sets variables that are not already in os.environ.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/fetch_results.py (reported line 83)May include surrounding context.

python
"""
Load FASTFOLD_API_KEY (and other vars) from a .env file so scripts work without
exporting the key in the shell. Searches current directory and parent directories
for .env; only sets variables that are not already in os.environ.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/get_viewer_link.py (reported line 64)May include surrounding context.

python
"""
Load FASTFOLD_API_KEY (and other vars) from a .env file so scripts work without
exporting the key in the shell. Searches current directory and parent directories
for .env; only sets variables that are not already in os.environ.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/load_env.py (reported line 2)May include surrounding context.

python
"""
Load FASTFOLD_API_KEY (and other vars) from a .env file so scripts work without
exporting the key in the shell. Searches current directory and parent directories
for .env; only sets variables that are not already in os.environ.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/load_env.py (reported line 13)May include surrounding context.

python
"""
Load FASTFOLD_API_KEY (and other vars) from a .env file so scripts work without
exporting the key in the shell. Searches current directory and parent directories
for .env; only sets variables that are not already in os.environ.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/wait_for_completion.py (reported line 64)May include surrounding context.

python
"""
Load FASTFOLD_API_KEY (and other vars) from a .env file so scripts work without
exporting the key in the shell. Searches current directory and parent directories
for .env; only sets variables that are not already in os.environ.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/load_env.py (reported line 20)May include surrounding context.

python
search_dirs.append(d)
        d = os.path.dirname(d)
    for dirpath in search_dirs:
        env_path = os.path.join(dirpath, ".env")
        if os.path.isfile(env_path):
            _parse_and_set(env_path)
            return

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs the agent to read environment variables, create or modify a .env file, read local files, and make authenticated network requests, but it declares no explicit tool scope or permissions. This creates a least-privilege failure: a host system may permit broader capabilities than users expect, increasing the chance of unauthorized file access, secret handling, or network actions under an underspecified trust boundary.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
84% confidence
Finding

The skill directs the agent to autonomously create a .env file in the workspace root and prepare the environment before explicit user confirmation for that file write. Even though the goal is convenience and secret safety, autonomous filesystem modification can violate user expectations, alter project state, and be abused in more permissive agent environments to persist configuration changes without sufficiently granular consent.

Content

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

md
**Agent — when the user needs to set the API key:** If `FASTFOLD_API_KEY` is not set:

1. **Copy the template for the user:** Copy `skills/fold/references/.env.example` to `.env` at the **workspace (project) root**. Create the `.env` file yourself (e.g. read the example file and write its contents to `.env`); do not ask the user to run the copy command.
2. **Guide the user:** Tell the user that a `.env` file has been created and they need to add their key. Say: *"Open the `.env` file in the project root and paste your FastFold API key after the `=` on the line `FASTFOLD_API_KEY=`. You can create a key at [FastFold API Keys](https://cloud.fastfold.ai/api-keys) if you don’t have one. Save the file when done."*
3. **Offer to run the workflow:** Add: *"Let me know when you’ve pasted your key—I can run the create job and the rest of the steps (wait for completion, fetch results, download CIF, viewer link) for you."* Do not give the user a list of commands to run themselves; offer to execute the scripts yourself once the key is set.
4. **Wait:** Do not run create job, wait, fetch, or download until the user confirms they have pasted and saved the key. After they confirm, run the scripts from the workspace root using the path `skills/fold/scripts/` (e.g. `python skills/fold/scripts/create_job.py ...`), not `.agents/...`.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The API exposes a direct control to make job results public, and the surrounding schema text does not clearly warn that enabling this can disclose job metadata, sequences, and result artifact URLs to unauthenticated callers. In this skill context, the payloads contain sensitive biological sequences and derived structures, so an unclear visibility toggle can easily cause accidental data exposure.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The JobInput.isPublic field description says results should be 'publicly accessible' but does not define scope, audience, or whether authentication is bypassed. In a protein-folding workflow, users may submit proprietary or unpublished sequences, so ambiguous wording increases the risk of unintended disclosure through misuse of the API.

Content

No source excerpt is available for this finding.