T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/sync_to_github.sh:339- Finding
Unrestricted Skill Path Allows Upload of Files Outside the Skills Directory
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly does what it says, but it can upload local files to GitHub and includes under-scoped token handling and destructive remote cleanup behavior that need careful review.
Install only if you are comfortable with a shell-based tool reading local skill files and writing them to GitHub. Use a fine-grained token limited to one private destination repository, avoid passing tokens on the command line, do not run cleanup unless you have reviewed the deletion list, and do not use --skill with anything except a simple verified skill directory name.
scripts/sync_to_github.sh:339Unrestricted Skill Path Allows Upload of Files Outside the Skills Directory
scripts/sync_to_github.sh:48Unsafe GitHub Token Handling Exposes Credentials Through Arguments, Output, and Plaintext Configuration
references/token-troubleshooting.md:34Documentation Requests an Overly Broad Classic GitHub Repository Scope
Token validation and repository permission inspection are not inherently malicious, but they are broader than the core synchronization promise and involve access to sensitive authentication context. When such actions are not clearly disclosed, users may provide tokens without understanding the full scope of access checks being performed.
Token validation and repository permission inspection are not inherently malicious, but they are broader than the core synchronization promise and involve access to sensitive authentication context. When such actions are not clearly disclosed, users may provide tokens without understanding the full scope of access checks being performed.
Token validation and repository permission inspection are not inherently malicious, but they are broader than the core synchronization promise and involve access to sensitive authentication context. When such actions are not clearly disclosed, users may provide tokens without understanding the full scope of access checks being performed.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
错误信息:
403 Resource not accessible by personal access token
原因:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
## 相关资源
- [GitHub Personal Access Tokens 文档](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)
- [GitHub API 限流说明](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting)
- [OAuth Scopes 参考](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps)
This script is designed to recursively delete all remote repository content not present in a hardcoded whitelist, which goes far beyond normal skill synchronization. Because it operates against the repository root and uses authenticated GitHub API DELETE calls, a user running it with a valid token could unintentionally destroy unrelated projects, documentation, or other collaborators' content.
The stated purpose is syncing local skills to GitHub, but the implementation includes a repo-wide purge capability that deletes any top-level content not listed in KEEP_SKILLS. That mismatch makes the behavior unexpectedly destructive and especially dangerous in an automation context where users may assume safe incremental sync semantics.
The skill clearly instructs use of shell commands and local scripts, but it does not declare any tool scope or allowed-tools boundary. This makes the capability less transparent to users and reviewers and increases the chance the agent will execute filesystem and network actions without explicit least-privilege constraints.
The skill description does not prominently warn that synchronization uploads local skill files and metadata to a remote GitHub repository. This omission undermines informed consent and can lead users to expose unpublished code, secrets, or internal metadata unintentionally.
The trigger phrase '备份我的技能' is broad enough to match normal conversational requests that do not necessarily imply uploading local content to GitHub. Overbroad triggering can cause the skill to activate in contexts where the user did not intend remote publication, increasing the chance of accidental data exposure.
The skill transmits authentication data and account-related requests to the GitHub API, which is expected for its purpose but still represents external transmission of sensitive context. If a user does not fully understand that their token and local skill metadata are being used against remote endpoints, this creates a real risk of credential misuse or unintended disclosure.
# 验证 Token 所有者
curl -s -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/user | jq -r '.login'
# 验证仓库权限
curl -s -H "Authorization: token $GITHUB_TOKEN" \
Checking repository permissions via the GitHub API is legitimate for sync functionality, but it still sends token-authenticated requests to a remote service and reveals repository targeting information. In the context of a skill that may auto-trigger on broad backup language, this becomes more dangerous because users may not realize a remote repo is being queried or prepared for writes.
curl -s -H "Authorization: token $GITHUB_TOKEN"
https://api.github.com/repos// | jq '.permissions'
## 输出格式
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.
# 你创建了 new-skill 目录
mkdir -p ~/.claude/skills/new-skill
# ... 编辑 SKILL.md 和脚本 ...
# 同步到 GitHub
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
# 你创建了 new-skill 目录
mkdir -p ~/.claude/skills/new-skill
# ... 编辑 SKILL.md 和脚本 ...
# 同步到 GitHub
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
# 你创建了 new-skill 目录
mkdir -p ~/.claude/skills/new-skill
# ... 编辑 SKILL.md 和脚本 ...
# 同步到 GitHub
The package description is entirely in Chinese, indicating a language-specific skill presentation with no accompanying option for users to choose another language or confirmation that the skill is intended only for a Chinese-language audience. This matches the policy category for language or locale constraints imposed without user opt-in.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
2. 手动创建仓库:
- 访问 https://github.com/new
- 输入仓库名称
- 点击 Create repository
3. 或使用 API 创建(需要 Token 有 repo 权限)
---
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
2. 手动创建仓库:
- 访问 https://github.com/new
- 输入仓库名称
- 点击 Create repository
3. 或使用 API 创建(需要 Token 有 repo 权限)
---
The document recommends persisting a GitHub personal access token in a shell startup file such as ~/.zshrc without warning that this stores the secret in plaintext on disk. That increases the chance of credential theft via local compromise, backups, screen sharing, dotfile sync, or accidental publication.
This shell script presents its title, usage notes, status messages, and remediation guidance in Chinese-only text, which imposes a specific language on users. The file does not offer a language choice, fallback, or justification that it is intended only for a Chinese-language or region-specific environment.
Natural-language strings throughout the file, including comments, usage text, error messages, and confirmation prompts, are Chinese-only. Per the policy, forcing a specific language without opt-in or documented locale-specific justification is a language policy violation.
This outbound request is not merely network communication; it performs authenticated DELETE operations against the GitHub API using the supplied token. In context, the call is part of a recursive purge workflow, so the external transmission directly causes remote destructive state changes rather than benign syncing.
log_info " [DRY-RUN] 删除:$item_path"
else
log_info " 删除:$item_path"
curl -s -X DELETE -H "Authorization: token $TOKEN" \
"https://api.github.com/repos/$OWNER/$REPO/contents/$item_path" \
-d "{\"message\":\"Cleanup\",\"sha\":\"$sha\",\"branch\":\"main\"}" > /dev/null
fi
This shell script's comments, usage text, prompts, and status messages are written in Chinese, including the help output and confirmation prompt. That imposes a specific language on users without any opt-in or alternative locale, which matches the language/locale policy violation criteria.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
create_repo() {
log_info "创建仓库 $OWNER/$REPO..."
response=$(curl -s -X POST \
-H "Authorization: token $TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/user/repos \
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# 更新 README
if [ -n "$readme_sha" ] && [ "$readme_sha" != "null" ]; then
# 已存在,更新
curl -s -X PUT -H "Authorization: token $TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$OWNER/$REPO/contents/README.md" \
-d "{\"message\":\"Update README with new skills: $synced_skills\",\"content\":\"$encoded\",\"sha\":\"$readme_sha\",\"branch\":\"main\"}" > /dev/null
No suspicious patterns detected.