Back to skill

Security audit

sprint-release-notes

Security checks for vulnerabilities and agentic risk

Overview

The skill matches a sprint release-notes workflow, but it handles broad GitHub credentials insecurely and can publish releases to repositories chosen from project-board data without a clear approval boundary.

Review carefully before installing. Use a fine-grained GitHub token limited to the exact approved repositories, do not store the token in the skill config or pass it on the command line, run dry-run first, and require a preflight list of target repositories before any release or comment is published. Treat contributor scoring and any notification webhook as separate opt-in behavior.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
references/config.yaml:1
Finding

GitHub PAT Stored in Plaintext and Exposed Through Process Arguments

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/generate_release_notes.py:646
Finding

Project-Controlled Repository Names Determine Authenticated Release and Tag Targets

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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (37)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

A second description/behavior mismatch indicates the skill may not actually do the per-repo publish flow it promises, instead relying on hardcoded or dry-run behavior. While this is partly an integrity/reliability issue rather than direct exploitation, security-relevant automation that silently targets the wrong repo or does not update expected releases can cause unauthorized changes, confusion, and unsafe operator assumptions.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

A second description/behavior mismatch indicates the skill may not actually do the per-repo publish flow it promises, instead relying on hardcoded or dry-run behavior. While this is partly an integrity/reliability issue rather than direct exploitation, security-relevant automation that silently targets the wrong repo or does not update expected releases can cause unauthorized changes, confusion, and unsafe operator assumptions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Contributor scoring and award selection are unjustified by the stated release-note purpose and require additional collection of reviews, code volume, and inferred difficulty metrics. This creates an unnecessary people-analytics function that can misuse repository data, generate sensitive HR-like judgments, and surprise users who only intended content publication.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The reference material describes behavior that diverges from the declared skill purpose and publication method. In a skill that is supposed to publish GitHub Release descriptions only, embedding repository file-write guidance creates a path for the agent to modify repository contents unexpectedly, which can lead to unauthorized commits, workflow abuse, or policy violations.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documented write path directly contradicts the manifest by instructing creation or update of repository files on the target branch. In context, this is more dangerous because the skill is expected to publish release notes as GitHub Release descriptions, so a user could invoke the skill expecting non-destructive metadata updates while the implementation instead performs source-repository writes.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The skill requires and directly consumes a GitHub PAT, which is a high-value credential capable of repository reads and writes depending on scope. Combined with command-line entry and automatic publishing, compromise of this token could let an attacker create or alter releases, read project metadata, and potentially access broader GitHub resources.

Content

Scanner excerpt · scripts/generate_release_notes.py (reported line 826)May include surrounding context.

python
def main():
    parser = argparse.ArgumentParser(description="Generate sprint release notes from GitHub Project Board")
    parser.add_argument("--board-url", required=True, help="GitHub Project Board URL")
    parser.add_argument("--pat", required=True, help="GitHub Personal Access Token")
    parser.add_argument("--release-repo", required=True, help="Repo to publish release notes (owner/repo)")
    parser.add_argument("--sprint-id", default=None, help="Specific sprint iteration ID")
    parser.add_argument("--output-dir", default=".", help="Directory to save local copy")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill instructs network access to GitHub APIs and publication of releases/comments, but it declares no explicit tool scope or permission boundaries. In an agent environment, this means the runtime may invoke broader capabilities than users expect, increasing the chance of unintended outbound requests or repository modifications with a supplied PAT.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description does not prominently warn that the skill can create or update GitHub Releases across multiple repositories and optionally post comments. Missing an upfront warning is dangerous because users may provide a PAT and project URL without realizing the skill performs cross-repo write operations, raising the likelihood of accidental mass modification.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger conditions are very broad and can activate the skill for generic phrases like 'generate release notes' or sprint summaries. Because the skill can publish releases and post issue comments, overbroad invocation increases the risk of unintended write actions on GitHub repositories when the user may have only wanted advice or draft text.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill expands from release-note publishing into contributor performance scoring and recognition generation, which is a materially different and more sensitive use of repository data. This enlarges data processing scope without clear user consent and can expose personnel analytics or bias-inducing outputs unrelated to the operational task.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 224)May include surrounding context.

Example (curl; use the user’s PAT and API version header as appropriate):

bash
curl -L -X PATCH \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-GitHub-Api-Version: 2026-03-10" \

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The configuration exposes an undeclared outbound integration channel via a Discord webhook that is not described in the skill metadata. Hidden or undocumented egress paths are dangerous because they can be used to exfiltrate release data, repository metadata, or other sensitive content outside the expected GitHub-only workflow, reducing operator visibility and consent.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · references/github-queries.md (reported line 29)May include surrounding context.

bash
# For GraphQL
curl -H "Authorization: bearer {PAT_TOKEN}" \
 -H "Content-Type: application/json" \
 -X POST https://api.github.com/graphql \
 -d '{"query": "..."}'

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill includes logic for scanning repository contents and PR file diffs to detect documentation changes, which exceeds what is needed to generate sprint release notes from project board items. This unnecessary expansion of scope increases data access and processing of repository content, creating avoidable privacy and least-privilege risks if the agent inspects sensitive files or unrelated materials.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Counting PR reviews per engineer is unrelated to generating sprint release notes and broadens the skill into employee activity analysis. That creates unnecessary collection and processing of personnel-related contribution data, which may expose behavioral metrics or be repurposed beyond the user's stated task.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The reference documents a direct repository write operation to the main branch without warning, confirmation, or safety constraints. Even if writes were intended, omission of user-facing warnings and approval checkpoints raises the risk of silent modification of production repositories and accidental persistence of generated content.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill claims to generate and publish sprint release notes, but it also evaluates contributors and assigns labels like 'Lead Engineer' and 'MVP'. That hidden expansion of scope processes personnel-performance data that users may not expect, creating privacy, trust, and governance risk especially in enterprise environments.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 51)May include surrounding context.

md
# Configuration & Constants
# ─────────────────────────────────────────────

GRAPHQL_URL = "https://api.github.com/graphql"
REST_BASE = "https://api.github.com"

FEATURE_LABELS = {"feature", "enhancement", "user-facing", "feat", "story"}

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 228)May include surrounding context.

md
# Configuration & Constants
# ─────────────────────────────────────────────

GRAPHQL_URL = "https://api.github.com/graphql"
REST_BASE = "https://api.github.com"

FEATURE_LABELS = {"feature", "enhancement", "user-facing", "feat", "story"}

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · references/github-queries.md (reported line 31)May include surrounding context.

md
# Configuration & Constants
# ─────────────────────────────────────────────

GRAPHQL_URL = "https://api.github.com/graphql"
REST_BASE = "https://api.github.com"

FEATURE_LABELS = {"feature", "enhancement", "user-facing", "feat", "story"}

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · references/github-queries.md (reported line 37)May include surrounding context.

md
# Configuration & Constants
# ─────────────────────────────────────────────

GRAPHQL_URL = "https://api.github.com/graphql"
REST_BASE = "https://api.github.com"

FEATURE_LABELS = {"feature", "enhancement", "user-facing", "feat", "story"}

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · scripts/generate_release_notes.py (reported line 37)May include surrounding context.

python
# Configuration & Constants
# ─────────────────────────────────────────────

GRAPHQL_URL = "https://api.github.com/graphql"
REST_BASE = "https://api.github.com"

FEATURE_LABELS = {"feature", "enhancement", "user-facing", "feat", "story"}

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · scripts/generate_release_notes.py (reported line 72)May include surrounding context.

python
if variables:
            payload["variables"] = variables
        for attempt in range(3):
            resp = requests.post(GRAPHQL_URL, headers=self.graphql_headers, json=payload)
            if resp.status_code == 403 and "rate limit" in resp.text.lower():
                reset_time = int(resp.headers.get("X-RateLimit-Reset", time.time() + 60))
                wait = max(reset_time - int(time.time()), 10)

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · scripts/generate_release_notes.py (reported line 106)May include surrounding context.

python
def rest_put(self, path, data):
        """PUT request to REST API."""
        url = f"{REST_BASE}{path}" if path.startswith("/") else path
        resp = requests.put(url, headers=self.rest_headers, json=data)
        resp.raise_for_status()
        return resp.json()

Tainted flow: 'data' from requests.post (line 80, network input) → requests.put (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/generate_release_notes.py (reported line 106)May include surrounding context.

python
def rest_put(self, path, data):
        """PUT request to REST API."""
        url = f"{REST_BASE}{path}" if path.startswith("/") else path
        resp = requests.put(url, headers=self.rest_headers, json=data)
        resp.raise_for_status()
        return resp.json()

Static analysis

No suspicious patterns detected.