T09 · Insecure Skill Coding Practices
Warning
- Location
- codeup_cli.py:47
- Finding
- Personal Access Token Exposed in Git Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `codeup_cli.py:47-54, 69-74`; `SKILL.md:62, 143-146, 174-178, 216` **Vulnerability Type**: Credential exposure through process arguments and diagnostic output **Risk Level**: Medium ### Vulnerable Code `codeup_cli.py:47-54`: ```python git_url = f"https://oauth2:{token}@codeup.aliyun.com/{project_path}.git" print(f"📥 正在克隆项目 {repo_name}...") subprocess.run( ['git', 'clone', '--quiet', '--no-tags', git_url, repo_path], check=True, capture_output=True, timeout=120 ) ``` `codeup_cli.py:69-74`: ```python except subprocess.CalledProcessError as e: return { 'success': False, 'error': f'Git 操作失败:{e.stderr.decode() if e.stderr else str(e)}' } ``` `SKILL.md:62` and `SKILL.md:216` document the same insecure credential-passing pattern: ```bash git clone --quiet "https://oauth2:$YUNXIAO_PERSONAL_TOKEN@codeup.aliyun.com/<path>.git" ``` `SKILL.md:143-146` duplicates the vulnerable implementation: ```python git_url = f"https://oauth2:{token}@codeup.aliyun.com/{project_path}.git" subprocess.run( ['git', 'clone', '--quiet', '--depth=1', git_url, repo_path], ``` ### Technical Analysis The personal access token is interpolated directly into an HTTPS repository URL and passed to `git clone` as a command-line argument. Although `subprocess.run` uses an argument list and is therefore not directly vulnerable to shell command injection, the resulting Git process contains the complete credential-bearing URL in its argument vector. Depending on operating-system process visibility controls, other local users, privileged monitoring agents, audit systems, crash reporters, or process telemetry collectors may be able to observe and retain the command line. The documented shell examples also expand the token before starting Git and may expose it through shell tracing, command auditing, or other terminal instrumentation. The exception handler returns Git's stderr without credential reda ...[truncated 1716 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Remove credentials from repository URLs and process arguments.** - Use a short-lived `GIT_ASKPASS` helper to provide the token only when Git requests credentials. - Set `GIT_TERMINAL_PROMPT=0` to prevent unexpected interactive prompts. - Ensure the helper file is created with owner-only permissions and deleted in a `finally` block. 2. **Prevent credential persistence.** - Do not configure a persistent global Git credential helper. - If a temporary credential helper is used, isolate it with a temporary Git configuration and ensure it does not write credentials to disk. 3. **Redact diagnostic output.** - Before displaying or logging stderr, replace the token and any URL user-information component with a fixed marker such as `[REDACTED]`. - Avoid returning raw subprocess diagnostics when they can contain authentication material. 4. **Correct the documentation.** - Remove all examples that embed `$YUNXIAO_PERSONAL_TOKEN` in a URL. - Document the secure authentication mechanism and warn users against passing tokens in command-line arguments. 5. **Apply least privilege and token lifecycle controls.** - Retain only the scopes required for repository reads. - Use short-lived tokens where supported and rotate any token that may have been exposed through process or command logs. - Restrict token access to the minimum necessary projects. ]]>
