T09 · Insecure Skill Coding Practices
- Location
scripts/lazygithub.sh:78- Finding
Unvalidated Repository Name Can Publicly Push an Existing Local Git Repository
- Content
View full analysis
Vulnerability Details
File Location:
scripts/lazygithub.sh, lines 7 and 78-106
Vulnerability Type: Unsafe local repository reuse and unintended public data exposure
Risk Level: Highbash VISIBILITY="public" if [[ "$ADD_LOCAL_README" == "true" ]]; then mkdir -p "$NAME" if [[ ! -f "$NAME/README.md" ]]; then cat > "$NAME/README.md" <<EOF # $NAME $DESCRIPTION EOF fi if [[ ! -d "$NAME/.git" ]]; then git -C "$NAME" init git -C "$NAME" add README.md git -C "$NAME" commit -m "chore: initial commit" fi fi CREATE_ARGS=(repo create "$NAME" "--$VISIBILITY" --description "$DESCRIPTION") if [[ -n "$HOMEPAGE" ]]; then CREATE_ARGS+=(--homepage "$HOMEPAGE") fi if [[ "$ADD_LOCAL_README" == "true" ]]; then CREATE_ARGS+=(--source "$NAME" --remote origin --push) fi gh "${CREATE_ARGS[@]}"Technical Analysis
The user-controlled
--namevalue serves two distinct purposes: the GitHub repository name and the local source-directory path. The script does not verify that this value is a simple repository name, does not reject path separators, and does not establish that the local directory was created by the current invocation.mkdir -p "$NAME"succeeds when the directory already exists. If that directory contains.git, the initialization branch is skipped, after which the existing repository is passed togh repo createthrough--source "$NAME". The--pushoption can then upload the repository's tracked files and Git history.This behavior is especially dangerous because repository visibility defaults to
public. Shell command injection is mitigated by array-based argument construction and quoting, but these measures do not prevent semantic path injection or unsafe reuse of an existing repository.Attack Path
- An attacker, untrusted instruction, or mistaken caller supplies
--namewith a value resolving to an existing local Git reposi ...[truncated 1210 chars]
- An attacker, untrusted instruction, or mistaken caller supplies
- Remediation
View remediation
Remediation Suggestions
- Separate the remote repository name from the local source path. Introduce an explicit
--sourceargument rather than interpreting--nameas both values. - Validate repository names against a strict allowlist and reject path separators,
.or..components, absolute paths, control characters, and option-like values. - Refuse to reuse any existing local directory by default. Require an explicit option such as
--allow-existing-sourcebefore operating on an existing Git repository. - Resolve an explicitly supplied source with a canonical-path operation and verify that it is within an expected workspace or another user-approved location.
- Before pushing an existing repository, display or inspect the remote, tracked files, commit history, and current branch, then require explicit confirmation.
- Do not default potentially reused repositories to public visibility. Require the caller to explicitly choose
--publicor--private, with an additional confirmation before public publication. - Check whether an
originremote already exists and refuse to replace or conflict with it without explicit authorization. - Consider creating new repositories in a securely generated empty working directory so pre-existing content cannot be selected accidentally.
- Separate the remote repository name from the local source path. Introduce an explicit
