Back to skill

Security audit

FairygitMother

Security checks for vulnerabilities and agentic risk

Overview

The skill is aligned with a third-party AI issue-fixing grid, but it needs Review because it runs unattended, stores service credentials locally, sends issue data externally, and ships an unsafe GitHub Actions workflow.

Review before installing. Use only with repositories and issues you are comfortable sending to fairygitmother.ai, avoid private or sensitive repos unless there is an explicit agreement, require per-task approval or repo allowlists, store service credentials in a managed secret store, and fix the GitHub Actions workflow to pass event data through environment variables with least-privilege permissions before copying it into a repository.

Vulnerability Patterns
  • 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
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
actions/fairygitmother.yml:29
Finding

GitHub Issue Content Is Directly Interpolated into a Shell Script

Content
View full analysis
Remediation
View remediation
request.json ``` 3. Submit the generated JSON file with `curl --data-binary @request.json`. 4. Declare explicit least-privilege workflow permissions, such as `contents: read` and `issues: read`, rather than relying on repository defaults. 5. Consider requiring a trusted approval mechanism before processing issues from untrusted users. 6. Add tests using issue titles and bodies containing quotes, command substitutions, newlines, and shell metacharacters. ]]>

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:6
Finding

Recurring Agent Tasks Are Controlled by an External Service Without a Sufficient Trust Boundary

Content
View full analysis
Remediation
View remediation

T02 · Agent Memory Poisoning

Error
Location
SKILL.md:23
Finding

Externally Influenced Content Is Persisted as Cross-Session Agent Guidance

Content
View full analysis
Remediation
View remediation

other

Warning
Location
actions/fairygitmother.yml:40
Finding

Full GitHub Issue Content Is Disclosed to a Third-Party Service Without Data Minimization

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a full autonomous workflow skill that participates in a distributed system to solve open source issues. However, the supplied code does not implement that workflow. It merely re-exports SDK components and utility functions from an external package. While those exports may support such a system, the actual code chunk itself is a thin module wrapper and not a skill that performs the described actions. This is a material description-to-behavior mismatch because the primary purpose and implemented capabilities differ substantially.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The skill instructs reading a local credentials.json containing a node API key on every activation. Accessing and operationalizing locally persisted secrets for a third-party service creates a high-risk credential surface, especially in a scheduled autonomous workflow where compromise or misuse of that file would enable authenticated remote actions.

Content

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

md
Every activation, start by loading your patrol state:

1. Read `{baseDir}/credentials.json` — your nodeId and apiKey
2. Read `{baseDir}/patrol-state.json` — your patrol history

If `credentials.json` doesn't exist, register first (see Credentials below).

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

This section couples normal patrol state handling with conditional credential initialization, making a secret-bearing file part of routine activation flow. That design encourages broad file access patterns and increases the chance that credential material is handled like ordinary state rather than protected as sensitive data.

Content

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

  1. Read {baseDir}/credentials.json — your nodeId and apiKey
  2. Read {baseDir}/patrol-state.json — your patrol history

If credentials.json doesn't exist, register first (see Credentials below). If patrol-state.json doesn't exist, create it:

json

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The skill explicitly creates a credential lifecycle for a third-party API key, including registering for it when absent. This is dangerous because it normalizes autonomous acquisition and use of secrets beyond the declared GitHub token, expanding both the credential inventory and the remote authority the agent can exercise.

Content

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

Credentials

If {baseDir}/credentials.json doesn't exist:

bash
curl -s -X POST "https://fairygitmother.ai/api/v1/nodes/register" \

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

Saving nodeId and apiKey directly to {baseDir}/credentials.json stores operational credentials in a predictable local path. Predictable plaintext storage raises the risk of accidental inclusion in logs, backups, workspace sync, or access by other skills/processes that can read the same directory.

Content

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

-d '{"displayName":"openclaw-node","capabilities":{"languages":[],"tools":["openclaw"]},"solverBackend":"openclaw"}'

text

Save the response to `{baseDir}/credentials.json`:
```json
{"nodeId":"node_xxx","apiKey":"mf_xxx"}

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Instructing the agent to delete and recreate credentials.json on authentication failure reinforces insecure file-based secret churn and can obscure incident response by discarding credential history. It also encourages repeated automated enrollment and credential rotation without administrative oversight.

Content

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

{"nodeId":"node_xxx","apiKey":"mf_xxx"}

text

If you get a 401 error, delete `{baseDir}/credentials.json` and re-register.

## Poll for Work

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill clearly instructs shell-based network and file operations (curl, reading/writing JSON state and credentials) but does not declare any tool scope or allowed-tools boundary. That mismatch weakens enforcement and review because a host may grant broader execution than users expect, especially for a cron-triggered skill that performs autonomous outbound actions.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill is designed for scheduled autonomous execution every 30 minutes and says 'The server decides what you do,' but it provides few trigger constraints or policy checks. That broad delegation increases risk of unreviewed external actions, repository interactions, and state changes being initiated without contextual user approval.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs the agent to read and persist a local credentials.json containing a FairygitMother API key even though only GITHUB_TOKEN is declared in metadata. This introduces hidden credential handling and persistent secret storage outside the declared contract, increasing the chance of unauthorized reuse, leakage, or operator surprise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill directs the agent to self-register with an external service, store returned credentials, and perform authenticated submissions, but it does not present a clear user-facing warning or consent gate for this persistent external account creation and data transmission. In practice, that can quietly bind a local agent to a remote service and create ongoing outbound communication channels.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

This command sends node capability data to fairygitmother.ai to register the local agent with a third-party service. External transmission itself is not always unsafe, but here it creates an unsolicited trust relationship and remote control plane for a cron-driven skill, making the undisclosed exfiltration and command-and-control aspects materially risky.

Content

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

If {baseDir}/credentials.json doesn't exist:

bash
curl -s -X POST "https://fairygitmother.ai/api/v1/nodes/register" \
  -H "Content-Type: application/json" \
  -d '{"displayName":"openclaw-node","capabilities":{"languages":[],"tools":["openclaw"]},"solverBackend":"openclaw"}'

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The comments make strong trust and safety claims about independent review, approval, and transparent PR opening, but the workflow itself only forwards issue metadata to a third-party service. This creates a deceptive security boundary: repository maintainers may enable the workflow based on assurances that are not technically enforced here, increasing the risk of unintended data sharing or downstream automated changes they did not meaningfully consent to.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 151)May include surrounding context.

md
LANGUAGE=$(curl -s \
            -H "Authorization: Bearer ${{ github.token }}" \
            "https://api.github.com/repos/$OWNER/$REPO/languages" \
            | jq -r 'to_entries | sort_by(-.value) | .[0].key // empty')

          RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 158)May include surrounding context.

md
LANGUAGE=$(curl -s \
            -H "Authorization: Bearer ${{ github.token }}" \
            "https://api.github.com/repos/$OWNER/$REPO/languages" \
            | jq -r 'to_entries | sort_by(-.value) | .[0].key // empty')

          RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 177)May include surrounding context.

md
LANGUAGE=$(curl -s \
            -H "Authorization: Bearer ${{ github.token }}" \
            "https://api.github.com/repos/$OWNER/$REPO/languages" \
            | jq -r 'to_entries | sort_by(-.value) | .[0].key // empty')

          RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 254)May include surrounding context.

md
LANGUAGE=$(curl -s \
            -H "Authorization: Bearer ${{ github.token }}" \
            "https://api.github.com/repos/$OWNER/$REPO/languages" \
            | jq -r 'to_entries | sort_by(-.value) | .[0].key // empty')

          RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · actions/fairygitmother.yml (reported line 37)May include surrounding context.

yaml
LANGUAGE=$(curl -s \
            -H "Authorization: Bearer ${{ github.token }}" \
            "https://api.github.com/repos/$OWNER/$REPO/languages" \
            | jq -r 'to_entries | sort_by(-.value) | .[0].key // empty')

          RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

This workflow sends issue and repository metadata to fairygitmother.ai, an external domain outside GitHub, which constitutes deliberate data exfiltration to a third party. Even if the feature is intended, it is security-relevant because issue bodies can contain sensitive operational details, and the workflow provides no validation, minimization, or trust guarantees about the recipient service.

Content

Scanner excerpt · actions/fairygitmother.yml (reported line 40)May include surrounding context.

yaml
"https://api.github.com/repos/$OWNER/$REPO/languages" \
            | jq -r 'to_entries | sort_by(-.value) | .[0].key // empty')

          RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
            "https://fairygitmother.ai/api/v1/bounties" \
            -H "Content-Type: application/json" \
            -d @- <<EOF

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The workflow posts repository and issue data, including title, body, labels, and inferred language, to an external service when a label is applied, but the executing step provides no explicit runtime warning or consent checkpoint. In a GitHub Actions context, labeling an issue can be done by maintainers who may not realize this action exfiltrates issue content to a third party, which is especially risky for private repositories or sensitive issue reports.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill claims GitHub-oriented maintenance behavior but also enrolls the agent in a third-party FairygitMother service and reports node/model analytics there. This undisclosed secondary data flow reduces transparency and can cause users to authorize GitHub work without realizing they are also joining an external coordination network.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The devDependency tsup is specified with a caret range, which allows newer minor/patch releases to be installed over time. This weakens build reproducibility and can expose the project to supply-chain risk if a newly resolved version is compromised or introduces a security flaw, especially because this skill builds code that participates in an automated agent ecosystem.

Content

Scanner excerpt · package.json (reported line 20)May include surrounding context.

json
"@fairygitmother/node": "workspace:*"
	},
	"devDependencies": {
		"tsup": "^8.3.0",
		"typescript": "^5.7.0"
	}
}

Unverifiable Dependency: tsup has 1 known advisory(ies) (CVE-2024-53384 (tsup DOM Clobbering vulnerability)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
78% confidence
Finding

The manifest references tsup without an exact version while static analysis indicates at least one known advisory may affect some tsup releases. Because the dependency is not pinned, it is not possible to verify from this file alone whether the installed version is vulnerable, creating uncertainty around build-time exposure to a known issue.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
88% confidence
Finding

The devDependency typescript is also unpinned via a caret range, so different installs may resolve to different compiler versions. While this is primarily a supply-chain and reproducibility concern rather than a direct runtime flaw, compromised or unexpectedly changed toolchain versions can affect build integrity.

Content

Scanner excerpt · package.json (reported line 21)May include surrounding context.

json
},
	"devDependencies": {
		"tsup": "^8.3.0",
		"typescript": "^5.7.0"
	}
}

Static analysis

No suspicious patterns detected.