Back to skill

Security audit

Ci Failure Fixer

Security checks for vulnerabilities and agentic risk

Overview

This skill is a CI auto-repair helper, but it can lead agents to make and push unattended repository changes with weak scope controls and includes a real script injection flaw.

Install only if you are comfortable with an agent inspecting GitHub Actions failures and potentially changing and pushing repository code. Use a dedicated low-privilege GitHub identity, set an explicit CI_REPOS allowlist, avoid unattended cron auto-repair, require human review before any commit or push, and do not expose CI_STATE_FILE to untrusted input.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/check-ci-failures.sh:11
Finding

Arbitrary Python Code Execution Through CI_STATE_FILE

Content
View full analysis

Vulnerability Details

File Location: scripts/check-ci-failures.sh, lines 11, 25-30, and 50-51
Vulnerability Type: Environment-variable-driven Python code injection
Risk Level: High

Vulnerable Code

bash
STATE_FILE="${CI_STATE_FILE:-$HOME/.openclaw/workspace/memory/ci-check-state.json}"

# Initialize state file if missing
if [ ! -f "$STATE_FILE" ]; then
  mkdir -p "$(dirname "$STATE_FILE")"
  echo '{"lastCheck":"2026-01-01T00:00:00Z"}' > "$STATE_FILE"
fi

LAST_CHECK=$(python3 -c "import json; print(json.load(open('$STATE_FILE'))['lastCheck'])" 2>/dev/null || echo "2026-01-01T00:00:00Z")

# Update last check time
python3 -c "import json; json.dump({'lastCheck':'$NOW'}, open('$STATE_FILE','w'))" 2>/dev/null

Technical Analysis

CI_STATE_FILE is an environment-controlled value. Although it is quoted for the shell, its expanded value is interpolated directly into Python source code passed to python3 -c.

Shell quoting does not make the resulting Python string literal safe. An attacker can include Python quote characters and expressions in the environment variable, causing the value to escape its intended string-literal context. For example, a path expression shaped like:

text
'+str(__import__("os").system("ATTACKER_COMMAND"))+'

causes os.system() to be evaluated while Python constructs the argument to open(). The command executes even if the subsequent file operation fails.

The same variable controls the destination used to initialize and update the state file. Without path restrictions, it can also target arbitrary locations writable by the process or interact with attacker-created symbolic links.

Attack Path

  1. An attacker gains control of the CI_STATE_FILE environment variable through cron configuration, an automation wrapper, a CI environment, or another invocation mechanism.
  2. The attacker supplies a value containing a Python expression that exits the ...[truncated 941 chars]
Remediation
View remediation

Remediation Suggestions

Never place environment-controlled values inside generated Python source. Pass paths and timestamps as positional arguments:

bash
LAST_CHECK=$(
  python3 -c \
    'import json, sys; print(json.load(open(sys.argv[1], encoding="utf-8"))["lastCheck"])' \
    "$STATE_FILE" 2>/dev/null ||
  echo "2026-01-01T00:00:00Z"
)

python3 -c \
  'import json, sys; json.dump({"lastCheck": sys.argv[2]}, open(sys.argv[1], "w", encoding="utf-8"))' \
  "$STATE_FILE" "$NOW"

Additional hardening should include:

  • Resolve the path to a canonical absolute path and enforce that it remains under an approved state directory.
  • Reject symbolic links and non-regular files.
  • Create the state directory with restrictive permissions such as 0700.
  • Create and replace the state file atomically with restrictive permissions such as 0600.
  • Fail explicitly when the state cannot be read or updated instead of silently suppressing all errors.
  • Run the scheduled task using a dedicated least-privileged account.

T08 · Insecure Dependencies

Warning
Location
references/fix-patterns.md:9
Finding

Unsafe Dependency and Tool Execution in Automated Repair Procedures

Content
View full analysis

Vulnerability Details

File Location: references/fix-patterns.md, lines 9-16, 46-54, and 72-80
Vulnerability Type: Unpinned package execution and unsafe dependency lifecycle processing
Risk Level: Medium

Vulnerable Code

bash
npm install
git add package-lock.json
git commit -m "fix: resolve dependency issue"
git push
bash
npx eslint --fix .
npx prettier --write .
git add -A
git commit -m "fix: resolve lint errors"
git push
bash
npx playwright install
npx playwright test --update-snapshots
git add -A
git commit -m "fix: update E2E snapshots"
git push

Technical Analysis

These commands are instructions for an AI agent rather than operations directly implemented by check-ci-failures.sh. However, SKILL.md directs the agent to consult and apply these repair patterns automatically.

npm install resolves dependencies and ordinarily executes package lifecycle scripts. Code in preinstall, install, postinstall, and related hooks therefore runs with the privileges and credentials of the repair agent.

The npx commands may execute project-local binaries, including binaries supplied by an attacker-controlled repository. Depending on npm configuration and package availability, npx can also download and execute packages that are not already installed. The commands do not enforce a reviewed lockfile, a trusted registry, package integrity policy, or an explicit prohibition against downloading missing tools.

The procedures subsequently commit and push the resulting changes, increasing the consequence of malicious package behavior.

Attack Path

  1. An attacker introduces a malicious dependency, lifecycle script, package configuration, or tool binary into a repository monitored by the Skill.
  2. The attacker causes a CI failure matching one of the documented dependency, lint, or Playwright patterns.
  3. The agent reads the repair documentation and ru ...[truncated 1019 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace npm install with lockfile-enforced npm ci wherever possible.
  • Use npm ci --ignore-scripts by default and enable individual lifecycle operations only after explicit review.
  • Require a committed and reviewed lockfile and fail if installation would modify it unexpectedly.
  • Configure an allowlisted package registry and enforce package integrity and provenance controls.
  • Do not allow npx to download missing tools implicitly.
  • Invoke only lockfile-pinned local tools, using an option that prohibits installation, such as an appropriately configured npm exec --no -- ....
  • Run installation and formatting operations inside an isolated container or sandbox without host credentials.
  • Provide GitHub credentials only after package execution has completed, and scope them to the specific repository and required operation.
  • Review staged changes and require human approval before committing or pushing.

T09 · Insecure Skill Coding Practices

Warning
Location
references/fix-patterns.md:22
Finding

Unrestricted Staging and Unattended Push of Generated Repository Changes

Content
View full analysis

Vulnerability Details

File Location: references/fix-patterns.md, lines 22-29, 46-54, and 72-80
Vulnerability Type: Overbroad repository mutation in automated repair workflows
Risk Level: Medium

Vulnerable Code

bash
npm test -- --update
git add -A
git commit -m "fix: update test snapshots"
git push
bash
npx eslint --fix .
npx prettier --write .
git add -A
git commit -m "fix: resolve lint errors"
git push
bash
npx playwright install
npx playwright test --update-snapshots
git add -A
git commit -m "fix: update E2E snapshots"
git push

Technical Analysis

git add -A stages every modification, deletion, and untracked file in the working tree. The workflow does not verify that staged files are limited to the expected snapshots or formatter output, nor does it inspect the staged diff for credentials, generated executables, workflow modifications, or unrelated local changes.

Snapshot-update commands also treat current program output as the new expected result. A malicious or defective test, application, dependency, or configuration can therefore generate attacker-selected snapshot content that is accepted and pushed without establishing that the behavioral change is legitimate.

Because SKILL.md describes automatic fixing and pushing, these instructions can be performed under an authenticated GitHub identity without an explicit human review gate.

Attack Path

  1. An attacker modifies repository code, tests, package behavior, or configuration so that a repair command creates additional or altered files.
  2. The attacker triggers a CI error matching a documented auto-fix pattern.
  3. The repair agent runs the corresponding snapshot, lint, formatting, or Playwright command.
  4. The invoked process writes expected outputs and one or more unrelated or malicious files into the working tree.
  5. git add -A stages all changes, including files outside the i ...[truncated 811 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace git add -A with explicit file allowlists derived from the expected repair operation.
  • Reject modifications to sensitive paths such as .github/workflows, package manifests, executable scripts, environment files, credentials, and deployment configuration unless separately approved.
  • Detect and reject unexpected untracked files, symbolic links, submodule changes, and file-mode changes.
  • Inspect git diff --cached --stat and git diff --cached before committing.
  • Add secret scanning and policy checks to the staged content.
  • Run tests without update flags first; permit snapshot updates only after validating that the behavioral change is intended.
  • Perform repairs in a clean, isolated checkout with no unrelated local files.
  • Push to a dedicated repair branch rather than directly to a protected branch.
  • Open a pull request and require human review and normal branch-protection checks before merging.
  • Use a narrowly scoped token that can write only to the specific repository and cannot modify protected branches or workflow files.
Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill promises autonomous diagnosis and repair of CI failures, including reading logs and pushing fixes, but the analyzed behavior does not match that description. This mismatch is dangerous because operators may trust the skill to safely remediate failures or understand its side effects, when in reality it may behave differently, causing unsafe automation assumptions and weakened review controls.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill advertises automatic fixes and pushes to repositories without an explicit warning that it may modify files, commit changes, and push to remote branches. In this context, the omission is especially dangerous because the skill targets CI failures across repositories and may run unattended as a cron job, magnifying the risk of unreviewed or harmful changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The cron automation section describes scheduled autonomous detection, modification, commit, push, and recheck behavior without any explicit warning or consent boundary. This is especially dangerous in this skill context because it enables repeated unattended writes to production repositories on a timer, magnifying the chance of destructive changes, supply-chain-triggered edits, commit loops, or persistent corruption from misclassified CI failures.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill describes behavior that can modify repositories and push changes, yet it declares no explicit tool or permission scope. That creates an authorization ambiguity where an agent/runtime may permit broader file-writing behavior than users expect, increasing the chance of unintended repository modifications.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The invocation text uses broad triggers such as requests to watch CI, fix build failures, or diagnose failed builds, which can cause the skill to activate in situations the user did not intend. Because this skill can lead to automated code changes and pushes, overbroad activation increases the risk of unexpected execution on sensitive repositories or workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This section instructs the agent to run package-management commands, commit, and push repository changes automatically, but it does not clearly warn that source control state will be modified and changes will be published upstream. In a skill specifically built for unattended CI repair, that omission is dangerous because users may enable it without realizing it can create and push code changes based solely on log pattern matching.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This workflow recommends broad auto-fix operations like updating snapshots and formatting/linting across the repository, followed by automatic commit and push, without warning about the scale or risk of those changes. In context, this is more dangerous because the skill is intended to react to CI failures autonomously, so a false pattern match or overbroad command could rewrite many files and publish them without human review.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

Using npx eslint --fix . without pinning a specific package version allows whatever version is currently resolved from the environment or registry to run. In an automation skill that modifies code and commits changes, this increases supply-chain and reproducibility risk because an unexpected or compromised package version could execute during unattended CI repair.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

Running npx prettier --write . without version pinning can fetch or resolve an unintended Prettier version, producing arbitrary code execution risk from the package supply chain and non-deterministic repository-wide edits. Because this skill is designed to auto-commit and push changes, even a transient bad version could propagate unsafe or destructive modifications to the repository.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

npx playwright install without an exact version may execute tooling not tied to the repository's audited dependency set. In a CI auto-repair workflow, this can introduce supply-chain exposure and environment drift during unattended remediation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

npx playwright test --update-snapshots without version pinning risks executing an unexpected Playwright package and making broad test-artifact changes under automation. Combined with auto-commit and push behavior, this can silently introduce unreviewed changes or run compromised tooling.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file header and implementation describe a checker that lists repositories, counts new failed runs, and prints a summary. Nothing in the code reads build logs, matches failure patterns, modifies repositories, or repairs CI issues, so the actual behavior is substantially narrower than the manifest's promised auto-fix functionality.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.