Back to skill

Security audit

GitHub Integration

Security checks for vulnerabilities and agentic risk

Overview

This GitHub skill is coherent, but it needs Review because it uses a write-capable token for high-impact repository actions with weak guardrails and some unsafe curl examples that could expose the token.

Install only if you are comfortable giving the agent GitHub authority. Use a fine-grained, short-lived PAT scoped to specific repositories and the minimum permissions needed, preferably read-only unless writes are required. Require explicit confirmation showing repo, branch, issue or PR number, path, and payload before comments, closes, merges, file updates, or deletions. Do not use the examples that print the token file, and quote/validate all curl URL inputs before running the documented commands.

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
SKILL.md:299
Finding
GitHub PAT Disclosure Through Unquoted Curl URL Expansion<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 299–305; equivalent unsafe expansions also occur at lines 330, 347, 363, and 411 **Vulnerability Type**: Shell word splitting leading to curl argument injection and credential disclosure **Risk Level**: High ### Vulnerable Code ```bash OWNER="octocat" REPO="hello-world" URL="${BASE_URL}/repos/${OWNER}/${REPO}/issues" curl -s -X POST ${URL} \ -H "Authorization: Bearer ${GH_TOKEN}" \ ``` The same unsafe pattern is used in other examples: ```bash curl -s ${URL} \ -H "Authorization: Bearer ${GH_TOKEN}" ``` ### Technical Analysis The URL is constructed from repository identifiers that would ordinarily be derived from user requests. Although the assignment to `URL` is quoted, `${URL}` is expanded without quotes when passed to `curl`. In a POSIX-compatible shell, an unquoted variable expansion is subject to word splitting and pathname expansion. If an attacker-controlled owner or repository value contains whitespace followed by another URL or curl option, the resulting value can be interpreted as multiple command-line arguments rather than one URL. This does not require shell metacharacters such as semicolons to be re-evaluated. Word splitting alone can introduce an additional URL into the existing curl invocation. Curl applies the explicitly configured `Authorization: Bearer ${GH_TOKEN}` header to requests made by that invocation, creating a credible path for the GitHub PAT to be transmitted to an attacker-controlled server. Authenticated communication with `https://api.github.com` is necessary for the Skill’s declared functionality. Allowing the same credential-bearing invocation to contact an unvalidated destination exceeds the minimum privileges required. ### Attack Path 1. An attacker provides a crafted repository owner or repository name containing whitespace and an attacker-controlled HTTPS URL. 2. The agent places that value into `OWNER` or `REPO` and constructs `URL`. 3. T ...[truncated 1347 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Quote every URL expansion passed to curl: ```bash curl -s -X POST "$URL" \ -H "Authorization: Bearer ${GH_TOKEN}" ``` Apply this correction to all affected commands, including lines 304, 330, 347, 363, and 411. 2. Validate user-derived GitHub identifiers before constructing a URL. Reject whitespace, control characters, URL delimiters, and values beginning with `-`. For example: ```bash validate_repo_component() { case "$1" in ""|*[!A-Za-z0-9_.-]*|-*) echo "Invalid GitHub repository identifier" >&2 return 1 ;; esac } validate_repo_component "$OWNER" || exit 1 validate_repo_component "$REPO" || exit 1 ``` 3. Pass the destination explicitly and terminate curl option parsing: ```bash curl -s -X POST --url "$URL" \ -H "Authorization: Bearer ${GH_TOKEN}" ``` Where compatible with the command structure, also use `--` before positional URL arguments. 4. Enforce an endpoint allowlist before attaching credentials. Confirm that the parsed scheme is HTTPS and the exact hostname is `api.github.com`; do not rely only on a string prefix check. 5. Use fine-grained, repository-specific, short-lived PATs. Separate read-only and write-capable credentials where practical, and avoid classic tokens with the broad `repo` scope. 6. Add negative tests using repository values containing spaces, leading dashes, additional URLs, tabs, and control characters. Verify that malformed values are rejected before curl executes. 7. Avoid printing the credential during setup verification. Replace the documented `cat ~/.config/openclaw/github_token` check with an existence and permissions check such as: ```bash test -r ~/.config/openclaw/github_token && stat ~/.config/openclaw/github_token ``` ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (47)

Credential Access

High
Category
Privilege Escalation
Content
- **name:** github-integration
- **version:** 1.0.0
- **description:** Operate GitHub repositories, issues, pull requests, files, and code search using the GitHub REST API via curl. Requires a GitHub Personal Access Token (PAT).
- **trigger phrases:** []
- **trigger phrases (natural English, ≥10):**
  - "create a GitHub issue"
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
- **name:** github-integration
- **version:** 1.0.0
- **description:** Operate GitHub repositories, issues, pull requests, files, and code search using the GitHub REST API via curl. Requires a GitHub Personal Access Token (PAT).
- **trigger phrases:** []
- **trigger phrases (natural English, ≥10):**
  - "create a GitHub issue"
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
- **name:** github-integration
- **version:** 1.0.0
- **description:** Operate GitHub repositories, issues, pull requests, files, and code search using the GitHub REST API via curl. Requires a GitHub Personal Access Token (PAT).
- **trigger phrases:** []
- **trigger phrases (natural English, ≥10):**
  - "create a GitHub issue"
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
### 2.1 GitHub Personal Access Token (PAT)

1. Go to **GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens** (or classic tokens).
2. Click **Generate new token** (fine-grained recommended).
3. Set an expiration date.
4. Under **Permissions**, grant at minimum:
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
Delete a file. Requires the file's current `sha` and a commit message.

```
DELETE /repos/{owner}/{repo}/contents/{path}
```

### 3.14 Search Code
Confidence
95% confidence
Finding
The skill exposes a direct file-deletion primitive whose target path is fully parameterized, making it susceptible to destructive misuse if the agent is tricked or the request is ambiguous. Because the action operates on remote repository contents, misuse can remove important files and disrupt builds or releases.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### 3.20 Remove Label from an Issue

```
DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}
```

---
Confidence
80% confidence
Finding
Removing labels is a parameterized remote state change that can affect issue routing, automation, and incident tracking. It is less severe than file deletion but still a real tool-abuse surface because a loosely triggered agent could change repository metadata unexpectedly.

Chaining Abuse

High
Category
Tool Misuse
Content
### Step 4 — Install jq (if missing)

```bash
sudo apt update && sudo apt install -y jq
```

### Step 5 — Test the Skill
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The skill defines triggers but does not specify when it must not activate or how to distinguish casual discussion from an execution request. In a skill that can create issues, merge PRs, and delete files, missing guardrails around activation raises the likelihood of unsafe or unintended operations.

Session Persistence

Medium
Category
Rogue Agent
Content
- **description:** Operate GitHub repositories, issues, pull requests, files, and code search using the GitHub REST API via curl. Requires a GitHub Personal Access Token (PAT).
- **trigger phrases:** []
- **trigger phrases (natural English, ≥10):**
  - "create a GitHub issue"
  - "open an issue on"
  - "comment on the PR"
  - "close the issue"
Confidence
85% confidence
Finding
The skill encourages reusable conversational triggers for actions that can modify remote repository state, effectively making a privileged session persistently available through common phrases. This increases the chance that ordinary discussion or indirect prompts re-engage the capability without a fresh trust decision.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are broad, natural-language GitHub requests that could easily appear in ordinary conversation and unintentionally invoke the skill. Because this skill can perform write and destructive actions against repositories, accidental activation materially increases the risk of unintended external actions.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The overview advertises destructive capabilities like file deletion and PR merge without prominently warning that these actions can be irreversible or operationally risky. Users may authorize actions without understanding their impact, especially when broad triggers can fire on casual requests.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# Option B — write to a secure file with restricted permissions
echo "ghp_xxxxxxxxxxxxxxxxxxxx" > ~/.config/openclaw/github_token
chmod 600 ~/.config/openclaw/github_token
```

Reference it in every curl call:
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

External Transmission

Medium
Category
Data Exfiltration
Content
chmod 600 ~/.config/openclaw/github_token
```

Reference it in every curl call:

```bash
GH_TOKEN="$(cat ~/.config/openclaw/github_token)"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
Many examples use `jq` to parse JSON responses. Install it if not present:

```bash
sudo apt install jq   # Debian/Ubuntu
brew install jq       # macOS
```
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
Many examples use `jq` to parse JSON responses. Install it if not present:

```bash
sudo apt install jq   # Debian/Ubuntu
brew install jq       # macOS
```
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

External Transmission

Medium
Category
Data Exfiltration
Content
URL="${BASE_URL}/repos/${OWNER}/${REPO}/issues/${ISSUE_NUM}"

curl -s -X PATCH ${URL} \
  -H "Authorization: Bearer ${GH_TOKEN}" \
  -H "Accept: application/vnd.github+json" \
  -d '{ "state": "closed", "state_reason": "completed" }' | \
Confidence
88% confidence
Finding
This command sends authenticated state-changing data to GitHub, closing an issue via an external network request. In context, external transmission is expected, but it is still security-relevant because broad activation and insufficient confirmations could cause unintended remote modifications.

External Transmission

Medium
Category
Data Exfiltration
Content
ISSUE_NUM="12345"
COMMENT_BODY="Thanks for reporting this! I can reproduce it. Labeling as bug."

curl -s -X POST \
  "${BASE_URL}/repos/${OWNER}/${REPO}/issues/${ISSUE_NUM}/comments" \
  -H "Authorization: Bearer ${GH_TOKEN}" \
  -H "Accept: application/vnd.github+json" \
Confidence
87% confidence
Finding
This authenticated POST transmits user-supplied comment content to an external service. The danger is not the existence of network access itself but that the skill can publish content remotely without explicit safeguards against accidental invocation or mis-targeting.

External Transmission

Medium
Category
Data Exfiltration
Content
REPO="myrepo"
URL="${BASE_URL}/repos/${OWNER}/${REPO}/pulls"

curl -s -X POST ${URL} \
  -H "Authorization: Bearer ${GH_TOKEN}" \
  -H "Accept: application/vnd.github+json" \
  -d '{
Confidence
90% confidence
Finding
Creating a pull request is an authenticated external write action that can affect development workflows, disclosures, and automated pipelines. Combined with broad triggers, this increases the chance of unintended repository changes or externally visible actions.

External Transmission

Medium
Category
Data Exfiltration
Content
PR_NUM="42"
METHOD="squash"    # merge | squash | rebase

curl -s -X PUT \
  "${BASE_URL}/repos/${OWNER}/${REPO}/pulls/${PR_NUM}/merge" \
  -H "Authorization: Bearer ${GH_TOKEN}" \
  -H "Accept: application/vnd.github+json" \
Confidence
94% confidence
Finding
Merging a pull request is a high-impact external action that can immediately change protected codebases and trigger deployment automation. Because the skill exposes this capability in conversational form, unintended or ambiguous requests could lead to irreversible operational consequences.

External Transmission

Medium
Category
Data Exfiltration
Content
COMMIT_MSG="docs: add new feature documentation"
CONTENT=$(echo -n "# New Feature\n\nThis feature does X." | base64 -w0)

curl -s -X PUT \
  "${BASE_URL}/repos/${OWNER}/${REPO}/contents/${FILE_PATH}" \
  -H "Authorization: Bearer ${GH_TOKEN}" \
  -H "Accept: application/vnd.github+json" \
Confidence
93% confidence
Finding
This command writes file content to a repository via an authenticated external request, enabling remote code or documentation changes. Without strict activation and review controls, such write operations can be abused or triggered accidentally to modify repository contents.

External Transmission

Medium
Category
Data Exfiltration
Content
# Step 2 — PUT with the SHA
NEW_CONTENT=$(echo -n "Updated README content here" | base64 -w0)

curl -s -X PUT \
  "${BASE_URL}/repos/${OWNER}/${REPO}/contents/${FILE_PATH}" \
  -H "Authorization: Bearer ${GH_TOKEN}" \
  -H "Accept: application/vnd.github+json" \
Confidence
93% confidence
Finding
Updating an existing file is a direct authenticated external modification to repository content and may alter code, docs, or configuration. In this skill, the risk is amplified by conversational triggers and absence of mandatory approval for write actions.

External Transmission

Medium
Category
Data Exfiltration
Content
SHA=$(curl -s "${BASE_URL}/repos/${OWNER}/${REPO}/contents/${FILE_PATH}" \
  -H "Authorization: Bearer ${GH_TOKEN}" | jq -r '.sha')

curl -s -X DELETE \
  "${BASE_URL}/repos/${OWNER}/${REPO}/contents/${FILE_PATH}" \
  -H "Authorization: Bearer ${GH_TOKEN}" \
  -H "Accept: application/vnd.github+json" \
Confidence
96% confidence
Finding
Deleting a file is a destructive authenticated external operation that can remove code or artifacts from a repository. Even though Git tracks history, deletion can still disrupt builds, workflows, or production processes and therefore warrants stronger safeguards.

External Transmission

Medium
Category
Data Exfiltration
Content
# URL-encode the query string
ENCODED_QUERY=$(echo -n "${QUERY}" | jq -sRr @uri)

curl -s "https://api.github.com/search/code?q=${ENCODED_QUERY}+repo:${OWNER}/${REPO}&per_page=${PER_PAGE}" \
  -H "Authorization: Bearer ${GH_TOKEN}" \
  -H "Accept: application/vnd.github+json" | \
  jq '{ total_count, items: [.items[] | { name, path, html_url }] }'
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# URL-encode the query string
ENCODED_QUERY=$(echo -n "${QUERY}" | jq -sRr @uri)

curl -s "https://api.github.com/search/code?q=${ENCODED_QUERY}+repo:${OWNER}/${REPO}&per_page=${PER_PAGE}" \
  -H "Authorization: Bearer ${GH_TOKEN}" \
  -H "Accept: application/vnd.github+json" | \
  jq '{ total_count, items: [.items[] | { name, path, html_url }] }'
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# URL-encode the query string
ENCODED_QUERY=$(echo -n "${QUERY}" | jq -sRr @uri)

curl -s "https://api.github.com/search/code?q=${ENCODED_QUERY}+repo:${OWNER}/${REPO}&per_page=${PER_PAGE}" \
  -H "Authorization: Bearer ${GH_TOKEN}" \
  -H "Accept: application/vnd.github+json" | \
  jq '{ total_count, items: [.items[] | { name, path, html_url }] }'
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

Detected: suspicious.exposed_secret_literal, suspicious.generated_source_template_injection

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
SKILL.md:64

User-controlled placeholder is embedded directly into generated source code.

Critical
Code
suspicious.generated_source_template_injection
Location
SKILL.md:565