T09 · Insecure Skill Coding Practices
- Location
- scripts/backup.sh:4
- Finding
- GitHub Token Exposure Through Command-Line Arguments and Persistent Remote Configuration## Vulnerability Details **File Location**: `scripts/backup.sh:4-7, 26-32`; related unsafe usage is documented in `SKILL.md:42-50, 106-115, 135-138` **Vulnerability Type**: Plaintext credential exposure **Risk Level**: High ### Vulnerable Code ```bash # Usage: ./backup.sh [github-username] [repo-name] [token] GITHUB_USER="${1}" REPO_NAME="${2}" TOKEN="${3}" BACKUP_MESSAGE="${4:-Backup: $(date +%Y-%m-%d)}" ``` ```bash CURRENT_REMOTE=$(git remote get-url origin 2>/dev/null || echo "") EXPECTED_REMOTE="https://x-access-token:${TOKEN}@github.com/${GITHUB_USER}/${REPO_NAME}.git" if [ "$CURRENT_REMOTE" != "$EXPECTED_REMOTE" ]; then git remote set-url origin "$EXPECTED_REMOTE" 2>/dev/null || \ git remote add origin "$EXPECTED_REMOTE" fi ``` The related documentation instructs the user to provide the token through the interactive conversation and recommends displaying configured remotes: ```text Then copy and send me the Token ``` ```bash git remote -v ``` ### Technical Analysis The backup script accepts a GitHub token as its third command-line argument and embeds it directly in an HTTPS Git remote URL. Git persists that URL in the repository's `.git/config` file. This creates several independent credential exposure channels: 1. The token can be retained in the agent conversation or transcript when the user submits it. 2. Command-line arguments may be visible to other local processes or users through process inspection while the script is running. 3. An interactive invocation may leave the complete command, including the token, in shell history. 4. The token remains in plaintext in `.git/config` after execution. 5. Diagnostic commands such as `git remote -v`, explicitly recommended by the documentation, can print the credential. 6. Logs, terminal captures, support records, or configuration backups may preserve the credential. The documentation states that API keys are excluded from backup content, but that claim does not mitigate the plaintext toke ...[truncated 1582 chars]
- Remediation
- ## Remediation Suggestions 1. Do not request or transmit access tokens through agent conversations. 2. Remove the token command-line parameter. Command-line arguments must not carry secrets. 3. Configure a token-free remote, such as: ```bash git remote set-url origin https://github.com/USER/REPOSITORY.git ``` 4. Authenticate through Git Credential Manager, GitHub CLI authentication, a protected credential helper, or SSH with a securely stored key. 5. If noninteractive HTTPS authentication is required, retrieve the secret at runtime from an approved secret manager and provide it through a short-lived credential helper without writing it into the remote URL. 6. Prefer a fine-grained, repository-specific GitHub token with only the minimum contents permissions necessary for backup pushes. Avoid classic tokens with broad `repo` scope. 7. Prevent diagnostic output from disclosing credentials. Do not display authenticated remote URLs, and redact user information from URLs before logging. 8. Check and remove existing credentials from `.git/config`, shell history, transcripts, logs, cron configuration, and related artifacts. 9. Immediately revoke and rotate any token previously used by this script because it may already have been retained in plaintext. 10. Restrict access permissions on the workspace and Git metadata as defense in depth, while recognizing that file permissions do not replace secure credential handling.
