Back to skill

Security audit

ForkZoo

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent with its GitHub pet purpose, but adoption grants broad GitHub authority and automatically enables and runs unreviewed GitHub Actions from a forked repository.

Install only if you are comfortable giving the skill a GitHub token that can create and modify repositories and workflows. Before running adoption, review the source pet repository and its workflow files, consider using a narrowly scoped temporary token, and be aware that it can publish a GitHub Pages site and run ongoing Actions in your account.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Error
Location
scripts/adopt.sh:69
Finding

Unreviewed Third-Party GitHub Actions Workflows Are Enabled and Executed

Content
View full analysis

Vulnerability Details

File Location: scripts/adopt.sh, lines 69-103
Vulnerability Type: Unsafe third-party workflow dependency and execution
Risk Level: High

Complete Code Snippet

bash
# Fork the repo
echo "🍴 Forking $SOURCE_REPO..."
FORK_RESPONSE=$(curl -s -X POST \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/$SOURCE_REPO/forks" \
  -d "{\"name\": \"$REPO_NAME\", \"default_branch_only\": true}")

FORK_URL=$(echo "$FORK_RESPONSE" | jq -r '.html_url')

if [ "$FORK_URL" == "null" ]; then
  echo "❌ Failed to fork repo"
  echo "$FORK_RESPONSE" | jq -r '.message // .errors[0].message // "Unknown error"'
  exit 1
fi

echo "✅ Forked to: $FORK_URL"

# Wait for fork to be ready
echo "⏳ Waiting for fork to initialize..."
sleep 5

# Enable GitHub Actions (they're disabled by default on forks)
echo "⚡ Enabling GitHub Actions..."
curl -s -X PUT \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/$GITHUB_USER/$REPO_NAME/actions/permissions" \
  -d '{"enabled": true, "allowed_actions": "all"}' > /dev/null

# Trigger the genesis workflow if it exists
echo "🐣 Initializing your pet..."
curl -s -X POST \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/$GITHUB_USER/$REPO_NAME/actions/workflows/genesis.yml/dispatches" \
  -d '{"ref": "main"}' 2>/dev/null || true

Technical Analysis

The adoption script forks a mutable repository controlled outside the audited Skill package, enables GitHub Actions with allowed_actions set to all, and immediately dispatches the forked genesis.yml workflow. The source repository is selected from the fixed forkZoo organization, but its content is not pinned to a reviewed commit and no workflow-content verifi ...[truncated 2241 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin adoption to a specific reviewed upstream commit or immutable release identifier instead of implicitly trusting the current default branch.
  2. Retrieve and inspect the workflow files at the pinned revision before enabling GitHub Actions. Verify their contents against a maintained checksum or signature.
  3. Do not dispatch genesis.yml automatically. Display the workflow source and require explicit user confirmation before enabling or running it.
  4. Replace "allowed_actions": "all" with a restrictive GitHub Actions policy that permits only GitHub-authored actions and an explicit allowlist of reviewed actions.
  5. Pin every referenced third-party action to a full commit SHA rather than a mutable branch or version tag.
  6. Configure default workflow permissions as read-only and grant write permissions only to individual jobs that demonstrably require them.
  7. Avoid exposing repository or organization secrets to the initialization workflow unless essential. Use narrowly scoped, environment-protected secrets where necessary.
  8. Validate that the forked repository and workflow commit match the expected source and revision before dispatch.
  9. Surface failures from the permissions and dispatch API calls instead of suppressing errors with redirection and || true, so users can verify the resulting security configuration.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (24)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script enables GitHub Actions with allowed_actions: "all", which permits unrestricted workflow execution in the forked repository. Because the repository is cloned from an external source and the script immediately triggers a workflow afterward, this creates a strong path to running unreviewed automation under the user's account and repository permissions.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill instructs the agent to run local shell scripts (./scripts/adopt.sh, status.sh, interact.sh) and to use a GitHub token with powerful repo and workflow scopes, but the manifest does not declare any explicit tool scope or permission boundary. This creates a mismatch between what the skill can induce an agent to do and what a user can readily review, increasing the chance of unexpected repository creation, workflow enablement, and token use.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest description includes broad triggers such as pet-related requests, tamagotchi mentions, forkzoo references, and 'my pet' queries, which can match ordinary conversation unrelated to GitHub automation. In this skill's context, accidental invocation is more dangerous because activation can lead to shell-script execution, GitHub token usage, forking repositories, and enabling GitHub Actions in the user's account.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The adoption flow says the script will fork a repository, enable GitHub Actions, initialize the pet, and requires a token with repo and workflow scopes, but the description does not prominently warn users about these account-changing operations. This lack of up-front disclosure is risky because users may invoke the skill thinking it is a harmless pet interaction, while it actually authorizes persistent code execution and repository changes on their GitHub account.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/adopt.sh (reported line 57)May include surrounding context.

sh
fi

# Check if repo already exists
EXISTING=$(curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: token $GITHUB_TOKEN" \
  "https://api.github.com/repos/$GITHUB_USER/$REPO_NAME")

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

Forking an external repository into the user's account is an intentional feature, but in this skill it is security-relevant because later steps automatically trust and activate that fork's automation and publication features. The danger comes from chaining an unreviewed external fork with subsequent security-sensitive configuration changes.

Content

Scanner excerpt · scripts/adopt.sh (reported line 73)May include surrounding context.

sh
FORK_RESPONSE=$(curl -s -X POST \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/$SOURCE_REPO/forks" \
  -d "{\"name\": \"$REPO_NAME\", \"default_branch_only\": true}")

FORK_URL=$(echo "$FORK_RESPONSE" | jq -r '.html_url')

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script does substantially more than 'adopt a pet': it modifies repository security settings, enables GitHub Actions, dispatches a workflow, and enables GitHub Pages on a newly forked repository. In this context, the mismatch between the user-facing description and the actual side effects is dangerous because the repo contents and workflows come from an external template, so adoption silently expands trust and execution surface beyond a simple fork.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
98% confidence
Finding

This outbound API call changes repository Actions permissions to enabled with unrestricted allowed actions. The risk is not mere transmission; it is that the request mutates security-sensitive settings in a way that permits arbitrary workflow/action execution from the forked content.

Content

Scanner excerpt · scripts/adopt.sh (reported line 92)May include surrounding context.

sh
# Enable GitHub Actions (they're disabled by default on forks)
echo "⚡ Enabling GitHub Actions..."
curl -s -X PUT \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/$GITHUB_USER/$REPO_NAME/actions/permissions" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
98% confidence
Finding

This API interaction is the concrete endpoint used to set unrestricted Actions permissions on the fork. In context, it directly weakens repository execution controls and materially increases the chance that unreviewed workflows or third-party actions will run with repository privileges.

Content

Scanner excerpt · scripts/adopt.sh (reported line 95)May include surrounding context.

sh
curl -s -X PUT \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/$GITHUB_USER/$REPO_NAME/actions/permissions" \
  -d '{"enabled": true, "allowed_actions": "all"}' > /dev/null

# Trigger the genesis workflow if it exists

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

This call dispatches genesis.yml automatically on the newly forked repository. Because the workflow content originates from the external template repo and the script does not verify or present it for review, it can execute arbitrary automation immediately after being enabled.

Content

Scanner excerpt · scripts/adopt.sh (reported line 103)May include surrounding context.

sh
curl -s -X POST \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/$GITHUB_USER/$REPO_NAME/actions/workflows/genesis.yml/dispatches" \
  -d '{"ref": "main"}' 2>/dev/null || true

# Enable GitHub Pages

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

This call enables GitHub Pages publishing on the newly forked repository, which exposes repository content at a public URL. In the context of a pet-adoption skill, auto-publishing is broader than necessary and may unintentionally expose unreviewed or user-specific content without clear consent.

Content

Scanner excerpt · scripts/adopt.sh (reported line 108)May include surrounding context.

sh
# Enable GitHub Pages
echo "🌐 Setting up GitHub Pages..."
curl -s -X POST \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/$GITHUB_USER/$REPO_NAME/pages" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

This request publishes the repository via GitHub Pages, creating external exposure for the fork's content. In a skill framed as simple pet adoption, silently making content available on a public site is a meaningful side effect that can surprise users and increase exposure of unreviewed material.

Content

Scanner excerpt · scripts/adopt.sh (reported line 111)May include surrounding context.

sh
curl -s -X POST \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/$GITHUB_USER/$REPO_NAME/pages" \
  -d '{"source": {"branch": "main", "path": "/"}}' 2>/dev/null || true

PAGES_URL="https://$GITHUB_USER.github.io/$REPO_NAME/"

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/interact.sh (reported line 41)May include surrounding context.

sh
# Try different workflow names
for WORKFLOW in "daily-evolution.yml" "evolve.yml" "daily.yml"; do
  RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
    -H "Authorization: token $GITHUB_TOKEN" \
    -H "Accept: application/vnd.github.v3+json" \
    "https://api.github.com/repos/$GITHUB_USER/$REPO_NAME/actions/workflows/$WORKFLOW/dispatches" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/adopt.sh (reported line 40)May include surrounding context.

sh
# Get current user
GITHUB_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/user | jq -r '.login')

# If no repo specified, try to find one
if [ -z "$REPO_NAME" ]; then

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/adopt.sh (reported line 59)May include surrounding context.

sh
# Get current user
GITHUB_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/user | jq -r '.login')

# If no repo specified, try to find one
if [ -z "$REPO_NAME" ]; then

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/gallery.sh (reported line 17)May include surrounding context.

sh
# Get current user
GITHUB_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/user | jq -r '.login')

# If no repo specified, try to find one
if [ -z "$REPO_NAME" ]; then

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/interact.sh (reported line 17)May include surrounding context.

sh
# Get current user
GITHUB_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/user | jq -r '.login')

# If no repo specified, try to find one
if [ -z "$REPO_NAME" ]; then

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/interact.sh (reported line 22)May include surrounding context.

sh
# Get current user
GITHUB_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/user | jq -r '.login')

# If no repo specified, try to find one
if [ -z "$REPO_NAME" ]; then

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/interact.sh (reported line 44)May include surrounding context.

sh
# Get current user
GITHUB_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/user | jq -r '.login')

# If no repo specified, try to find one
if [ -z "$REPO_NAME" ]; then

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/status.sh (reported line 17)May include surrounding context.

sh
# Get current user
GITHUB_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/user | jq -r '.login')

# If no repo specified, try to find one
if [ -z "$REPO_NAME" ]; then

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/status.sh (reported line 25)May include surrounding context.

sh
# Get current user
GITHUB_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/user | jq -r '.login')

# If no repo specified, try to find one
if [ -z "$REPO_NAME" ]; then

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/status.sh (reported line 45)May include surrounding context.

sh
# Get current user
GITHUB_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/user | jq -r '.login')

# If no repo specified, try to find one
if [ -z "$REPO_NAME" ]; then

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/status.sh (reported line 51)May include surrounding context.

sh
# Get current user
GITHUB_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/user | jq -r '.login')

# If no repo specified, try to find one
if [ -z "$REPO_NAME" ]; then

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

This shell script makes authenticated network requests using the GITHUB_TOKEN, which means user/account-associated data is sent to GitHub. Although the script prints status messages about fetching pet data, it does not explicitly disclose that it will use the token to query the user's account and repositories.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.