This is an automated email from the ASF dual-hosted git repository.
hello-stephen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new ad4b8b87bdf [fix](ci) harden GitHub Actions workflows against
injection and module shadowing (#63486)
ad4b8b87bdf is described below
commit ad4b8b87bdf49de4f437dd4f0e31d0164e022b0b
Author: Dongyang Li <[email protected]>
AuthorDate: Thu May 21 18:40:25 2026 +0800
[fix](ci) harden GitHub Actions workflows against injection and module
shadowing (#63486)
## Problem
Two security issues in GitHub Actions workflows:
**1. Expression injection — `comment-to-trigger-teamcity.yml`**
`COMMENT_REPEAT_TIMES` was extracted from the PR comment body via an
unanchored regex (`grep -E` uses substring matching, so `(
[1-9]*[0-9]+)*` can match zero times). The raw value was then written
directly to `$GITHUB_OUTPUT` without validation. Subsequent steps
interpolate it as `${{ steps.parse.outputs.COMMENT_REPEAT_TIMES }}`
inside `run:` blocks, which GitHub Actions evaluates **before** the
shell runs — equivalent to string-splicing untrusted input into a shell
script.
Any user who can comment on an open PR could inject shell commands into
the runner.
**2. Python module shadowing — `license-eyes.yml`**
The `pull_request_target` workflow checks out the fork's HEAD and runs
`python3` with an inline heredoc. Python's `sys.path` includes `''` (the
current working directory) by default, so a fork-supplied `yaml.py` at
the repo root would be imported instead of the stdlib `yaml` module.
Combined with `pull_request_target`'s elevated permissions, this allows
arbitrary code execution.
## Fix
- **`comment-to-trigger-teamcity.yml`**: validate `COMMENT_REPEAT_TIMES`
is a non-negative integer (or empty) immediately after extraction,
before writing to `$GITHUB_OUTPUT`. Non-numeric values are discarded.
- **`license-eyes.yml`**: add `persist-credentials: false` to the fork
checkout; strip `''` and `'.'` from `sys.path` before `import yaml` to
prevent local module shadowing.
## Test
Workflow logic is unchanged for valid inputs. The validation only
affects malformed `COMMENT_REPEAT_TIMES` values (non-numeric strings),
which had no defined behavior before.
Co-authored-by: Claude Sonnet 4.6 <[email protected]>
---
.github/workflows/comment-to-trigger-teamcity.yml | 4 ++++
.github/workflows/license-eyes.yml | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/.github/workflows/comment-to-trigger-teamcity.yml
b/.github/workflows/comment-to-trigger-teamcity.yml
index 92336f430f5..d706e171a65 100644
--- a/.github/workflows/comment-to-trigger-teamcity.yml
+++ b/.github/workflows/comment-to-trigger-teamcity.yml
@@ -133,6 +133,10 @@ jobs:
reg="run
(buildall|compile|p0|p1|feut|beut|cloudut|external|clickbench|cloud_p0|cloud_p1|vault_p0|nonConcurrent|performance|check_coverage)(
[1-9]*[0-9]+)*"
COMMENT_TRIGGER_TYPE="$(echo -e "${COMMENT_BODY}" | xargs | grep -E
"${reg}" | awk -F' ' '{print $2}' | sed -n 1p | sed 's/\r//g')"
COMMENT_REPEAT_TIMES="$(echo -e "${COMMENT_BODY}" | xargs | grep -E
"${reg}" | awk -F' ' '{print $3}' | sed -n 1p | sed 's/\r//g')"
+ if [[ -n "${COMMENT_REPEAT_TIMES}" && ! "${COMMENT_REPEAT_TIMES}" =~
^[0-9]+$ ]]; then
+ echo "COMMENT_REPEAT_TIMES '${COMMENT_REPEAT_TIMES}' is not a valid
number, ignoring."
+ COMMENT_REPEAT_TIMES=""
+ fi
echo "COMMENT_TRIGGER_TYPE=${COMMENT_TRIGGER_TYPE}" | tee -a
"$GITHUB_OUTPUT"
echo "COMMENT_REPEAT_TIMES=${COMMENT_REPEAT_TIMES}" | tee -a
"$GITHUB_OUTPUT"
diff --git a/.github/workflows/license-eyes.yml
b/.github/workflows/license-eyes.yml
index 2fbccb9c0d3..c0705d67481 100644
--- a/.github/workflows/license-eyes.yml
+++ b/.github/workflows/license-eyes.yml
@@ -47,6 +47,7 @@ jobs:
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
+ persist-credentials: false
- name: Get changed files
if: github.event_name == 'pull_request_target'
@@ -90,6 +91,9 @@ jobs:
CHANGED_FILES: ${{ steps.changed-files.outputs.added_modified }}
run: |
python3 - <<'EOF'
+ import sys
+ # Prevent fork-supplied files from shadowing stdlib modules
+ sys.path = [p for p in sys.path if p not in ('', '.')]
import yaml, os
with open('.licenserc.yaml') as f:
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]