T09 · Insecure Skill Coding Practices
- Location
scripts/github_indexer.py:28- Finding
GitHub CLI Argument Injection in Repository Indexing
- Content
View full analysis
dict: result = subprocess.run( f'"{GH_EXE}" {args}', capture_output=True, encoding="utf-8", errors="replace" ) ``` Representative user-controlled call: ```python def fetch_issues(repo: str, state: str = "all", limit: int = 100) -> List[GitHubItem]: data = gh_list(f"issue list --repo {repo} --state {state} --limit {limit} --json number,title,body,state,author,labels,url,createdAt,updatedAt") ``` Related call sites construct commands in the same manner: ```python data = gh_list(f"pr list --repo {repo} --state {state} --limit {limit} --json number,title,body,state,author,labels,url,createdAt,updatedAt,isDraft") ``` ```python data = gh(f"repo view {repo} --json name,description,stargazerCount,url,languages,repositoryTopics") ``` ### Technical Analysis The repository name and other arguments are interpolated into a single command-line string. On the intended Windows environment, process argument parsing can interpret spaces and quotes in an attacker-controlled repository value as argument boundaries. The input is not validated as an `owner/repository` identifier. Because `shell=False` is used, this is not a confirmed shell-metacharacter or arbitrary operating-system command injection vulnerability. It is an argument-injection weakness: crafted input may introduce additional GitHub CLI flags or otherwise alter the intended request. The command executes under the operator's existing authenticated GitHub CLI identity. ### Attack Path 1. An attacker able to invoke the script supplies a crafted value for the positional `repo` argument. 2. The value passes through `argparse` without repository-format validation. 3. ` ...[truncated 705 chars]- Remediation
View remediation
