T05 · Unauthorized Access and Privilege Escalation
Warning
- Location
- scripts/triage.py:20
- Finding
- Forced Removal of Caller-Provided GitHub Tokens Can Cause Privileged Credential Fallback<![CDATA[ ## Vulnerability Details **File Location**: `scripts/triage.py:20-27`; also prescribed by `SKILL.md:26-29`, `SKILL.md:36-41`, and `SKILL.md:193-198` **Vulnerability Type**: Authentication context confusion and violation of least privilege **Risk Level**: Medium ### Vulnerable Code From `scripts/triage.py:20-27`: ```python def run_gh(args: list[str]) -> str: """Run gh CLI command with token env cleared.""" env_prefix = ["env", "-u", "GH_TOKEN", "-u", "GITHUB_TOKEN"] result = subprocess.run( env_prefix + ["gh"] + args, capture_output=True, text=True, ) ``` The corresponding mandatory instruction in `SKILL.md:26-29` is: ```bash **ALWAYS use this pattern for ALL gh commands:** ```bash env -u GH_TOKEN -u GITHUB_TOKEN gh <command> ``` ``` The pattern is also applied to the documented write operations in `SKILL.md:193-198`: ```bash env -u GH_TOKEN -u GITHUB_TOKEN gh pr comment <NUMBER> --body "This PR appears to duplicate #XXX. Please coordinate with the other author or close if redundant." ``` ```bash env -u GH_TOKEN -u GITHUB_TOKEN gh pr edit <NUMBER> --add-label "duplicate" env -u GH_TOKEN -u GITHUB_TOKEN gh pr edit <NUMBER> --add-label "needs-review" ``` ### Technical Analysis The Skill unconditionally removes `GH_TOKEN` and `GITHUB_TOKEN` before every GitHub CLI invocation. These environment variables are commonly used to provide a deliberately scoped, invocation-specific credential. Removing them causes `gh` to use another available authentication source, typically a credential previously stored by `gh auth login`. This creates authentication-context confusion: the caller may expect the operation to use a restricted token, but the Skill silently substitutes the locally stored GitHub identity. That identity may have access to private repositories or broader write privileges. The behavior is not necessary for the declared PR-triage functionality. Reading pull-request metadata only requires a suitably sc ...[truncated 2362 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the forced token deletion and invoke GitHub CLI directly: ```python result = subprocess.run( ["gh"] + args, capture_output=True, text=True, check=False, ) ``` 2. Preserve caller-provided `GH_TOKEN` and `GITHUB_TOKEN` values. If authentication isolation is required, accept an explicit credential or profile option instead of silently switching identities. 3. Verify the selected identity before accessing repository data, for example with `gh auth status`, and display the hostname and account to the caller. 4. Document the minimum required token permissions: - Read-only repository and pull-request metadata for normal triage. - Separate, explicitly approved write permissions only for comment or label actions. 5. Separate read and write execution paths. Require explicit confirmation immediately before any mutation, and verify that the selected identity and target repository match the user's request. 6. Fail closed when no explicitly approved authentication source is available rather than falling back silently to a stored credential. 7. Update every example and the “ALWAYS use this pattern” instruction in `SKILL.md` so it no longer mandates removal of environment-provided tokens. ]]>
