mirror of https://github.com/openclaw/openclaw.git
fix(scripts/pr): shell-escape env file values to prevent command injection via branch names
This commit is contained in:
parent
f865a5455e
commit
d15d7d0962
|
|
@ -114,15 +114,16 @@ prepare_gates() {
|
|||
fi
|
||||
fi
|
||||
|
||||
cat > .local/gates.env <<EOF_ENV
|
||||
PR_NUMBER=$pr
|
||||
DOCS_ONLY=$docs_only
|
||||
CHANGELOG_REQUIRED=$changelog_required
|
||||
GATES_MODE=$gates_mode
|
||||
LAST_VERIFIED_HEAD_SHA=$current_head
|
||||
FULL_GATES_HEAD_SHA=${previous_full_gates_head:-}
|
||||
GATES_PASSED_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
EOF_ENV
|
||||
# Security: shell-escape values to prevent command injection when sourced.
|
||||
printf '%s=%q\n' \
|
||||
PR_NUMBER "$pr" \
|
||||
DOCS_ONLY "$docs_only" \
|
||||
CHANGELOG_REQUIRED "$changelog_required" \
|
||||
GATES_MODE "$gates_mode" \
|
||||
LAST_VERIFIED_HEAD_SHA "$current_head" \
|
||||
FULL_GATES_HEAD_SHA "${previous_full_gates_head:-}" \
|
||||
GATES_PASSED_AT "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
> .local/gates.env
|
||||
|
||||
echo "docs_only=$docs_only"
|
||||
echo "changelog_required=$changelog_required"
|
||||
|
|
|
|||
|
|
@ -78,13 +78,14 @@ prepare_init() {
|
|||
git checkout -B "pr-$pr-prep" "pr-$pr"
|
||||
git fetch origin main
|
||||
|
||||
cat > .local/prep-context.env <<EOF_ENV
|
||||
PR_NUMBER=$pr
|
||||
PR_HEAD=$head
|
||||
PR_HEAD_SHA_BEFORE=$pr_head_sha_before
|
||||
PREP_BRANCH=pr-$pr-prep
|
||||
PREP_STARTED_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
EOF_ENV
|
||||
# Security: shell-escape values to prevent command injection via malicious branch names.
|
||||
printf '%s=%q\n' \
|
||||
PR_NUMBER "$pr" \
|
||||
PR_HEAD "$head" \
|
||||
PR_HEAD_SHA_BEFORE "$pr_head_sha_before" \
|
||||
PREP_BRANCH "pr-$pr-prep" \
|
||||
PREP_STARTED_AT "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
> .local/prep-context.env
|
||||
|
||||
if [ ! -f .local/prep.md ]; then
|
||||
cat > .local/prep.md <<EOF_PREP
|
||||
|
|
@ -173,14 +174,15 @@ prepare_push() {
|
|||
- Verified PR head contains origin/main.
|
||||
EOF_PREP
|
||||
|
||||
cat > .local/prep.env <<EOF_ENV
|
||||
PR_NUMBER=$PR_NUMBER
|
||||
PR_AUTHOR=$contrib
|
||||
PR_HEAD=$PR_HEAD
|
||||
PR_HEAD_SHA_BEFORE=$pushed_from_sha
|
||||
PREP_HEAD_SHA=$prep_head_sha
|
||||
COAUTHOR_EMAIL=$coauthor_email
|
||||
EOF_ENV
|
||||
# Security: shell-escape values to prevent command injection via propagated PR_HEAD.
|
||||
printf '%s=%q\n' \
|
||||
PR_NUMBER "$PR_NUMBER" \
|
||||
PR_AUTHOR "$contrib" \
|
||||
PR_HEAD "$PR_HEAD" \
|
||||
PR_HEAD_SHA_BEFORE "$pushed_from_sha" \
|
||||
PREP_HEAD_SHA "$prep_head_sha" \
|
||||
COAUTHOR_EMAIL "$coauthor_email" \
|
||||
> .local/prep.env
|
||||
|
||||
ls -la .local/prep.md .local/prep.env >/dev/null
|
||||
|
||||
|
|
@ -245,14 +247,15 @@ prepare_sync_head() {
|
|||
- Prepare gates reran automatically when the sync rebase changed the prep head.
|
||||
EOF_PREP
|
||||
|
||||
cat > .local/prep.env <<EOF_ENV
|
||||
PR_NUMBER=$PR_NUMBER
|
||||
PR_AUTHOR=$contrib
|
||||
PR_HEAD=$PR_HEAD
|
||||
PR_HEAD_SHA_BEFORE=$pushed_from_sha
|
||||
PREP_HEAD_SHA=$prep_head_sha
|
||||
COAUTHOR_EMAIL=$coauthor_email
|
||||
EOF_ENV
|
||||
# Security: shell-escape values to prevent command injection via propagated PR_HEAD.
|
||||
printf '%s=%q\n' \
|
||||
PR_NUMBER "$PR_NUMBER" \
|
||||
PR_AUTHOR "$contrib" \
|
||||
PR_HEAD "$PR_HEAD" \
|
||||
PR_HEAD_SHA_BEFORE "$pushed_from_sha" \
|
||||
PREP_HEAD_SHA "$prep_head_sha" \
|
||||
COAUTHOR_EMAIL "$coauthor_email" \
|
||||
> .local/prep.env
|
||||
|
||||
ls -la .local/prep.md .local/prep.env >/dev/null
|
||||
|
||||
|
|
|
|||
|
|
@ -288,9 +288,10 @@ push_prep_head_to_pr_branch() {
|
|||
exit 1
|
||||
}
|
||||
git branch -D "pr-$pr-verify" 2>/dev/null || true
|
||||
cat > "$result_env_path" <<EOF_ENV
|
||||
PUSH_PREP_HEAD_SHA=$prep_head_sha
|
||||
PUSHED_FROM_SHA=$pushed_from_sha
|
||||
PR_HEAD_SHA_AFTER_PUSH=$pr_head_sha_after
|
||||
EOF_ENV
|
||||
# Security: shell-escape values to prevent command injection when sourced.
|
||||
printf '%s=%q\n' \
|
||||
PUSH_PREP_HEAD_SHA "$prep_head_sha" \
|
||||
PUSHED_FROM_SHA "$pushed_from_sha" \
|
||||
PR_HEAD_SHA_AFTER_PUSH "$pr_head_sha_after" \
|
||||
> "$result_env_path"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
set_review_mode() {
|
||||
local mode="$1"
|
||||
cat > .local/review-mode.env <<EOF_ENV
|
||||
REVIEW_MODE=$mode
|
||||
REVIEW_MODE_SET_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
EOF_ENV
|
||||
# Security: shell-escape values to prevent command injection when sourced.
|
||||
printf '%s=%q\n' \
|
||||
REVIEW_MODE "$mode" \
|
||||
REVIEW_MODE_SET_AT "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
> .local/review-mode.env
|
||||
}
|
||||
|
||||
review_claim() {
|
||||
|
|
@ -482,10 +483,11 @@ review_tests() {
|
|||
exit 1
|
||||
fi
|
||||
|
||||
{
|
||||
echo "REVIEW_TESTS_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
echo "REVIEW_TEST_TARGET_COUNT=$#"
|
||||
} > .local/review-tests.env
|
||||
# Security: shell-escape values to prevent command injection when sourced.
|
||||
printf '%s=%q\n' \
|
||||
REVIEW_TESTS_AT "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
REVIEW_TEST_TARGET_COUNT "$#" \
|
||||
> .local/review-tests.env
|
||||
|
||||
echo "review tests passed and were observed in output"
|
||||
}
|
||||
|
|
@ -502,11 +504,12 @@ review_init() {
|
|||
local mb
|
||||
mb=$(git merge-base origin/main "pr-$pr")
|
||||
|
||||
cat > .local/review-context.env <<EOF_ENV
|
||||
PR_NUMBER=$pr
|
||||
MERGE_BASE=$mb
|
||||
REVIEW_STARTED_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
EOF_ENV
|
||||
# Security: shell-escape values to prevent command injection when sourced.
|
||||
printf '%s=%q\n' \
|
||||
PR_NUMBER "$pr" \
|
||||
MERGE_BASE "$mb" \
|
||||
REVIEW_STARTED_AT "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
> .local/review-context.env
|
||||
set_review_mode main
|
||||
|
||||
printf '%s\n' "$json" | jq '{number,title,url,state,isDraft,author:.author.login,base:.baseRefName,head:.headRefName,headSha:.headRefOid,headRepo:.headRepository.nameWithOwner,additions,deletions,files:(.files|length)}'
|
||||
|
|
|
|||
|
|
@ -55,18 +55,33 @@ write_pr_meta_files() {
|
|||
|
||||
printf '%s\n' "$json" > .local/pr-meta.json
|
||||
|
||||
cat > .local/pr-meta.env <<EOF_ENV
|
||||
PR_NUMBER=$(printf '%s\n' "$json" | jq -r .number)
|
||||
PR_URL=$(printf '%s\n' "$json" | jq -r .url)
|
||||
PR_AUTHOR=$(printf '%s\n' "$json" | jq -r .author.login)
|
||||
PR_BASE=$(printf '%s\n' "$json" | jq -r .baseRefName)
|
||||
PR_HEAD=$(printf '%s\n' "$json" | jq -r .headRefName)
|
||||
PR_HEAD_SHA=$(printf '%s\n' "$json" | jq -r .headRefOid)
|
||||
PR_HEAD_REPO=$(printf '%s\n' "$json" | jq -r .headRepository.nameWithOwner)
|
||||
PR_HEAD_REPO_URL=$(printf '%s\n' "$json" | jq -r '.headRepository.url // ""')
|
||||
PR_HEAD_OWNER=$(printf '%s\n' "$json" | jq -r '.headRepositoryOwner.login // ""')
|
||||
PR_HEAD_REPO_NAME=$(printf '%s\n' "$json" | jq -r '.headRepository.name // ""')
|
||||
EOF_ENV
|
||||
# Security: shell-escape all values with printf %q to prevent command injection
|
||||
# via malicious branch names containing $() or backticks. See GHSA-xxxx-xxxx-xxxx.
|
||||
local pr_number pr_url pr_author pr_base pr_head pr_head_sha
|
||||
local pr_head_repo pr_head_repo_url pr_head_owner pr_head_repo_name
|
||||
pr_number=$(printf '%s\n' "$json" | jq -r .number)
|
||||
pr_url=$(printf '%s\n' "$json" | jq -r .url)
|
||||
pr_author=$(printf '%s\n' "$json" | jq -r .author.login)
|
||||
pr_base=$(printf '%s\n' "$json" | jq -r .baseRefName)
|
||||
pr_head=$(printf '%s\n' "$json" | jq -r .headRefName)
|
||||
pr_head_sha=$(printf '%s\n' "$json" | jq -r .headRefOid)
|
||||
pr_head_repo=$(printf '%s\n' "$json" | jq -r .headRepository.nameWithOwner)
|
||||
pr_head_repo_url=$(printf '%s\n' "$json" | jq -r '.headRepository.url // ""')
|
||||
pr_head_owner=$(printf '%s\n' "$json" | jq -r '.headRepositoryOwner.login // ""')
|
||||
pr_head_repo_name=$(printf '%s\n' "$json" | jq -r '.headRepository.name // ""')
|
||||
|
||||
printf '%s=%q\n' \
|
||||
PR_NUMBER "$pr_number" \
|
||||
PR_URL "$pr_url" \
|
||||
PR_AUTHOR "$pr_author" \
|
||||
PR_BASE "$pr_base" \
|
||||
PR_HEAD "$pr_head" \
|
||||
PR_HEAD_SHA "$pr_head_sha" \
|
||||
PR_HEAD_REPO "$pr_head_repo" \
|
||||
PR_HEAD_REPO_URL "$pr_head_repo_url" \
|
||||
PR_HEAD_OWNER "$pr_head_owner" \
|
||||
PR_HEAD_REPO_NAME "$pr_head_repo_name" \
|
||||
> .local/pr-meta.env
|
||||
}
|
||||
|
||||
list_pr_worktrees() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue