Back to skill

Security audit

GitHub Issue Writer

Security checks for vulnerabilities and agentic risk

Overview

This skill is a GitHub issue writer with expected GitHub submission behavior, but its documented shell and API examples handle user-provided issue text unsafely enough to need review before installation.

Install only if you are comfortable with a skill that can draft and, after confirmation, submit GitHub issues using your authenticated GitHub tooling. Before using submission, review the exact repository, title, body, labels, and assignees, remove secrets from logs or stack traces, and prefer a safer implementation that passes arguments without a shell and serializes JSON properly.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:183
Finding
Shell Command Injection Through Untrusted Issue Fields<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 183–188 **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code ```bash gh issue create \ --repo owner/repo \ --title "<title>" \ --body "<body>" \ --label "bug,priority:high" \ --assignee "@me" ``` ### Technical Analysis The skill directs the agent to place generated issue titles and bodies directly into a shell command. These values originate from user-provided descriptions and therefore must be treated as untrusted. Double quotes do not prevent all shell evaluation. Command substitutions such as `$(command)` and backtick expressions remain active inside double-quoted shell arguments. Embedded quotation marks can also terminate an argument if the agent generates the final command as shell text. Consequently, an attacker can construct issue content that changes the command's interpretation or executes additional local commands. The risk arises before `gh` processes the arguments: the local shell interprets the generated command and evaluates malicious syntax. ### Attack Path 1. An attacker asks the skill to create an issue containing a malicious title or body, such as content with command substitution or shell metacharacters. 2. The skill preserves the attacker-controlled content while drafting the issue. 3. The user authorizes submission. 4. The agent substitutes the generated title or body into the documented `gh issue create` shell command. 5. The local shell evaluates the injected syntax before launching `gh`. 6. The injected command executes with the operating-system privileges and environment of the agent process. ### Impact Assessment Successful exploitation permits arbitrary local command execution with the privileges of the account running the agent. Depending on that account's access, an attacker could: - Read or modify files accessible to the agent. - Access source repositories and local Git configuration. - Obtain environmen ...[truncated 341 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not construct submission commands by concatenating or interpolating issue content into shell source code. - Invoke `gh` through a process-execution API that accepts an argument array and does not invoke a shell. - Store the issue body in a securely created temporary file and use `gh issue create --body-file <file>`. Create the file with restrictive permissions and delete it after submission. - Pass the title as a discrete process argument rather than embedding it in a shell command string. - Apply strict validation to repository identifiers, labels, assignees, and milestones. For example, repository identifiers should match an allowlisted `owner/repository` format. - Display the final destination repository and metadata to the user before performing the authenticated operation. - Add tests using titles and bodies containing quotes, backticks, `$()`, semicolons, newlines, and other shell metacharacters to verify that they remain literal data. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:193
Finding
Unsafe JSON and Shell Construction in GitHub API Fallback<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 193–202 **Vulnerability Type**: Improper neutralization of untrusted data in JSON and shell commands **Risk Level**: Medium ### Vulnerable Code ```bash curl -s -X POST \ -H "Authorization: Bearer $GH_TOKEN" \ -H "Accept: application/vnd.github+json" \ https://api.github.com/repos/{owner}/{repo}/issues \ -d '{ "title": "<title>", "body": "<body>", "labels": ["bug"], "assignees": [] }' ``` ### Technical Analysis The API fallback shows untrusted issue fields being inserted directly into a hand-written JSON document. No JSON serialization or escaping mechanism is specified. Titles and bodies can legitimately contain quotation marks, backslashes, line breaks, and control characters. Raw substitution of these values can produce malformed JSON or allow attacker-controlled content to alter the intended JSON structure. For example, an injected quotation mark can terminate the `body` string and introduce additional object members. The JSON document is also enclosed in a single-quoted shell argument. If an implementation performs textual substitution while constructing the final shell command, an apostrophe in an issue field can terminate the shell string. Additional shell syntax could then be interpreted as a command. Whether this escalates to command execution depends on how the agent performs substitution, but the documented construction provides no safe handling for either shell syntax or JSON syntax. The `{owner}` and `{repo}` placeholders are likewise not constrained in the documented fallback. They should not be copied into a command URL without validating that they are legitimate GitHub repository identifiers. ### Attack Path 1. An attacker supplies an issue title or body containing JSON delimiters, quotation marks, an apostrophe, or shell metacharacters. 2. The skill includes the content in the generated issue draft. 3. The user authorizes API submission. 4. ...[truncated 1163 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Generate the request body with a real JSON serializer rather than textual substitution. - For a shell-based implementation, use a construction such as `jq -n --arg title "$title" --arg body "$body" '{title: $title, body: $body, labels: ["bug"], assignees: []}'`. - Write serialized JSON to a securely created file and submit it with `curl --data-binary @request.json`, or pipe serializer output directly to `curl --data-binary @-`. - Prefer a process-execution API with an argument array instead of composing a shell command. - Validate the repository owner and name using a strict allowlist before building the API URL. - Use `curl --fail-with-body --show-error` and check the HTTP status rather than relying only on response text. - Never print the `Authorization` header or token in diagnostic output. - Test serialization with quotation marks, apostrophes, backslashes, Unicode, multiline bodies, and JSON-like attacker input. ]]>
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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Vague Triggers

Medium
Confidence
93% confidence
Finding
The skill’s activation description is broad enough to trigger on generic problem statements, which can cause the agent to invoke issue-writing behavior in contexts where the user only wanted discussion or diagnosis. That increases the chance of collecting context and moving toward issue submission without sufficiently explicit user intent.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
3. **What happened / what's wanted?** (the raw description, error, or idea)
4. **Optional:** Labels, assignee, milestone, environment details

If the user gives you enough context, proceed without asking — draft and show for confirmation.

---
Confidence
75% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

External Transmission

Medium
Category
Data Exfiltration
Content
> **Prerequisites for submission:**
> - `gh` CLI (authenticated via `gh auth login`) — preferred path
> - `GH_TOKEN` env var — required for the curl API fallback
> - `git` — used to detect the repo from `git remote get-url origin`
>
> Drafting (Steps 1–5) works without any of these.
Confidence
82% confidence
Finding
This section authorizes optional submission through external tools and repo auto-detection, creating a path for transmitting user-provided content to GitHub and for interacting with the local repository context. Even though it says submission happens only on commands like 'submit' or 'go ahead', the skill still defines a ready-made exfiltration path to an external service using authenticated tooling.

External Transmission

Medium
Category
Data Exfiltration
Content
curl -s -X POST \
  -H "Authorization: Bearer $GH_TOKEN" \
  -H "Accept: application/vnd.github+json" \
  https://api.github.com/repos/{owner}/{repo}/issues \
  -d '{
    "title": "<title>",
    "body": "<body>",
Confidence
90% confidence
Finding
The curl fallback sends issue content and authentication-derived requests directly to the GitHub API, which is an external transmission channel. If invoked with sensitive logs, stack traces, secrets, or private project details embedded in the drafted issue body, the skill could leak confidential information to a remote third party repository.

Static analysis

No suspicious patterns detected.