Back to skill

Security audit

Developer Workflow Automation

Security checks for vulnerabilities and agentic risk

Overview

This GitHub skill mostly matches its purpose, but it can make persistent changes to GitHub accounts and exposes an under-documented pull request action with weak argument controls.

Review before installing. Use a fine-grained GitHub token limited to specific repositories and permissions, avoid broad classic repo tokens where possible, and only invoke write actions after checking the target repo, visibility, branch, title, and body. Treat the hidden/under-documented pull request action and unrestricted issue extra fields as reasons for manual review or remediation before routine use.

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

Warning
Location
api.js:171
Finding
Authenticated GitHub API Path Injection Through Unvalidated Repository Name## Vulnerability Details **File Location**: `api.js:171-198`; permissive action schema at `index.js:88-96` **Vulnerability Type**: Authenticated API path injection with unrestricted request-body properties **Risk Level**: Medium ### Vulnerable Code ```js async function createIssue(args, context) { const username = await getUsername(context); const { repo, title, body } = args; if (!title) { throw new Error('Issue title required'); } const url = `${GITHUB_API}/repos/${username}/${repo}/issues`; const response = await fetch(url, { method: 'POST', headers: getAuthHeaders(context), body: JSON.stringify({ title, body: body || '', ...(args.extra || {}) }) }); if (!response.ok) { const error = await response.json(); throw new Error(`Failed to create issue: ${error.message || response.status}`); } const issue = await response.json(); return { number: issue.number, title: issue.title, url: issue.html_url, state: issue.state }; } ``` The corresponding action schema permits an unrestricted `extra` object: ```js create_issue: { description: 'Create a new issue', parameters: { type: 'object', properties: { repo: { type: 'string' }, title: { type: 'string' }, body: { type: 'string' }, extra: { type: 'object' } }, required: ['repo', 'title'] }, handler: createIssueHandler }, ``` ### Technical Analysis The attacker-controlled `repo` value is directly interpolated into a URL path without validation or path-segment encoding: ```js `${GITHUB_API}/repos/${username}/${repo}/issues` ``` Values containing traversal components such as `../` can be normalized by the URL implementation before the request ...[truncated 2571 chars]
Remediation
## Remediation Suggestions 1. Validate repository and owner names before constructing URLs. Reject path separators, traversal components, query delimiters, fragments, control characters, and percent-encoded equivalents. ```js const GITHUB_NAME_PATTERN = /^[A-Za-z0-9_.-]+$/; function validateGitHubName(value, field) { if ( typeof value !== 'string' || !value || !GITHUB_NAME_PATTERN.test(value) || value === '.' || value === '..' ) { throw new Error(`Invalid GitHub ${field}`); } return value; } ``` 2. Encode every dynamic URL path segment independently: ```js const safeUsername = encodeURIComponent( validateGitHubName(username, 'username') ); const safeRepo = encodeURIComponent( validateGitHubName(repo, 'repository name') ); const url = `${GITHUB_API}/repos/${safeUsername}/${safeRepo}/issues`; ``` 3. Remove the unrestricted `extra` object. Explicitly copy only supported issue fields: ```js const payload = { title, body: body || '', ...(Array.isArray(args.labels) ? { labels: args.labels } : {}), ...(Array.isArray(args.assignees) ? { assignees: args.assignees } : {}), ...(Number.isInteger(args.milestone) ? { milestone: args.milestone } : {}) }; ``` 4. Add `additionalProperties: false` to the action schema and define strict types, lengths, ranges, and array-item constraints for every accepted property. 5. Apply equivalent path validation and encoding to all functions that interpolate `owner`, `repo`, username, branch, or other caller-controlled values into GitHub API URLs. 6. Use fine-grained GitHub tokens restricted to the required repositories and operations. Avoid classic tokens with broad `repo` scope where possible. 7. Add regression tests covering `../`, encoded traversal, `/`, `?`, `#`, b ...[truncated 72 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (23)

Credential Access

High
Category
Privilege Escalation
Content
- OpenClaw gateway running
- Node.js 18+
- GitHub account with a Personal Access Token (PAT)

## Setup
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
- OpenClaw gateway running
- Node.js 18+
- GitHub account with a Personal Access Token (PAT)

## Setup
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
- OpenClaw gateway running
- Node.js 18+
- GitHub account with a Personal Access Token (PAT)

## Setup
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
- OpenClaw gateway running
- Node.js 18+
- GitHub account with a Personal Access Token (PAT)

## Setup
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
- OpenClaw gateway running
- Node.js 18+
- GitHub account with a Personal Access Token (PAT)

## Setup
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
A second description-behavior mismatch indicates the artifact may be a test harness or validation wrapper rather than the end-user skill described, while also lacking declared issue-creation behavior and including auth validation side effects. This kind of mismatch is dangerous because reviewers and users may authorize a skill under false assumptions about what code actually runs and what data it touches.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
A second description-behavior mismatch indicates the artifact may be a test harness or validation wrapper rather than the end-user skill described, while also lacking declared issue-creation behavior and including auth validation side effects. This kind of mismatch is dangerous because reviewers and users may authorize a skill under false assumptions about what code actually runs and what data it touches.

Session Persistence

Medium
Category
Rogue Agent
Content
- 📋 **List Repos** — View your repositories with filters
- 📊 **Get Repo Details** — Stars, forks, language, last updated
- 🔄 **Check CI Status** — Monitor CI/CD pipelines
- 📝 **Create Issues** — Open issues from conversation
- 📁 **Create Repos** — Create new repositories
- 🔍 **Search Repos** — Find repos by name/query
- 📊 **Recent Activity** — View recent commits
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README advertises destructive/write-capable actions such as creating issues and repositories but does not clearly warn users that invoking these commands will modify their GitHub account and may have side effects. In an agent-driven context, unclear disclosure increases the risk of unintended repository creation or issue spam through prompt misunderstanding or overbroad automation.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill advertises capabilities that require sensitive operations (network access to GitHub APIs and use of environment/config credentials) but does not explicitly declare tool scope such as allowed tools or permissions. That weakens policy enforcement and reviewability, making it easier for a skill to overreach or for operators to miss what resources it can access.

Session Persistence

Medium
Category
Rogue Agent
Content
You: Check CI status on my main project
Bot: [shows CI/CD status]

You: Create an issue about the bug
Bot: [creates the issue]
```
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The declared API surface includes state-changing capabilities to create repositories and pull requests, but the finding indicates those capabilities are omitted from the manifest. This creates a security transparency gap: users, orchestrators, or policy systems may believe the skill is read-only or less privileged than it actually is, enabling unintended write actions against GitHub resources.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The module exposes write-capable operations beyond the stated skill description/manifest scope, including repository and pull request creation. Scope drift is dangerous because users and orchestrators may grant trust based on the declared capabilities, while the code can perform additional state-changing actions against GitHub using available credentials.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
createIssue sends a POST to create issues and merges arbitrary extra fields from args.extra into the API payload, all without confirmation or field restrictions. This makes it easy for an agent or attacker-controlled prompt input to perform unintended issue creation, add labels/assignees/milestones, or otherwise manipulate project workflow.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
createRepo issues a direct POST to GitHub to create a repository using configured credentials, with no in-code confirmation, approval, or policy check. In an agent setting, this enables unintended or prompt-induced external side effects, potentially creating public or private repositories without the user's informed consent.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
createPullRequest performs a state-changing POST that can open pull requests on repositories accessible to the token, without any user-facing confirmation or branch/repo authorization guardrails. In an autonomous skill context, this can be abused by prompt injection or accidental invocation to spam repos, trigger CI, or propose unwanted changes.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
This interface exposes state-changing GitHub actions such as creating issues, repositories, and pull requests without any visible confirmation, approval, or safety gating in the skill contract. In an agent setting, that increases the risk of unintended or prompt-induced actions being executed against a user's GitHub account or organization, especially because repository management operations can have persistent external effects.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The exported skill description says only 'Query and manage GitHub repositories', while the action set also enables repository creation and pull-request creation. In an agent/tool-selection context, understated capability descriptions can mislead orchestrators or users into invoking write-capable actions they did not realize were available, increasing the risk of unintended state-changing operations on GitHub.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This skill exposes state-changing GitHub actions like create_issue, create_repo, and create_pull_request without any visible confirmation, warning, or additional authorization gate in this file. In conversational agent environments, that increases the chance of prompt-induced or mistaken execution that creates public artifacts, changes project state, or leaks information through unintended repository/PR creation.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This code accesses a sensitive credential via process.env.GITHUB_TOKEN and sends it in the Authorization header on outbound network requests. Although the test purpose implies GitHub API use, this file provides no explicit warning or disclosure comment near the sensitive environment-variable access or token transmission.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The manifest describes the skill as able to list repositories, check CI status, create issues, search repositories, and view recent activity. These type definitions additionally expose parameters and result types for creating repositories and creating pull requests, which are write capabilities not mentioned in the stated description.

Missing User Warnings

Low
Confidence
82% confidence
Finding
This declaration file exposes state-changing operations such as creating issues, repositories, and pull requests, but the file contains no confirmation prompt, user-facing warning, or explanatory disclosure around those actions. Because this is a code file and these operations can modify external resources, the absence of any visible warning in the file meets the missing user warning criterion.

Context-Inappropriate Capability

Low
Confidence
81% confidence
Finding
The manifest describes a GitHub skill for querying and managing repositories. In this test file, the code directly reads a GitHub token from process environment variables, which is not itself part of the user-facing GitHub management purpose and introduces credential-handling capability into the skill's test logic.

Static analysis

No suspicious patterns detected.