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]

Reply via email to