Skip to content

Commit be40250

Browse files
authored
fix(security): prevent pwn-request vulnerability in gen_docs workflow (#4850)
1 parent a9a3497 commit be40250

1 file changed

Lines changed: 42 additions & 66 deletions

File tree

.github/workflows/pr_auto_run_gen_docs.yaml

Lines changed: 42 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ name: Auto run gen_docs.py and commit changes to PR
33
on:
44
pull_request_target:
55
types: [opened, synchronize]
6+
paths:
7+
- 'xinference/model/llm/llm_family.json'
8+
- 'xinference/model/embedding/model_spec.json'
9+
- 'xinference/model/rerank/model_spec.json'
10+
- 'xinference/model/image/model_spec.json'
11+
- 'xinference/model/audio/model_spec.json'
12+
- 'xinference/model/video/model_spec.json'
613

714
permissions:
815
contents: write
@@ -13,18 +20,18 @@ jobs:
1320
if: startsWith(github.event.pull_request.head.ref, 'chore/models-sync/')
1421
runs-on: ubuntu-latest
1522
steps:
16-
- name: Checkout base repository (trusted scripts)
23+
- name: Checkout base branch (trusted code)
1724
uses: actions/checkout@v4
1825
with:
19-
ref: ${{ github.event.pull_request.base.ref }}
26+
ref: ${{ github.event.pull_request.base.sha }}
2027
repository: ${{ github.repository }}
21-
path: main
28+
path: base
2229
fetch-depth: 0
2330

24-
- name: Checkout PR head branch (working copy)
31+
- name: Checkout PR head (data only)
2532
uses: actions/checkout@v4
2633
with:
27-
ref: ${{ github.event.pull_request.head.ref }}
34+
ref: ${{ github.event.pull_request.head.sha }}
2835
repository: ${{ github.event.pull_request.head.repo.full_name }}
2936
path: pr
3037
fetch-depth: 0
@@ -41,24 +48,7 @@ jobs:
4148
echo "run=false" >> $GITHUB_OUTPUT
4249
exit 0
4350
fi
44-
45-
HEAD_SHA="$(git rev-parse HEAD)"
46-
BASE_SHA="${{ github.event.pull_request.base.sha }}"
47-
RANGE="$BASE_SHA...$HEAD_SHA"
48-
echo "Diff range (full PR): $RANGE"
49-
50-
CHANGED_FILES="$(git diff --name-only "$RANGE" || true)"
51-
echo "Changed files in PR range:"
52-
echo "$CHANGED_FILES"
53-
54-
RUN="false"
55-
for f in $CHANGED_FILES; do
56-
case "$f" in
57-
xinference/model/llm/llm_family.json|xinference/model/embedding/model_spec.json|xinference/model/rerank/model_spec.json|xinference/model/image/model_spec.json|xinference/model/audio/model_spec.json|xinference/model/video/model_spec.json)
58-
RUN="true"; break;;
59-
esac
60-
done
61-
echo "run=$RUN" >> $GITHUB_OUTPUT
51+
echo "run=true" >> $GITHUB_OUTPUT
6252
6353
- name: Set up Python
6454
if: steps.decide.outputs.run == 'true'
@@ -73,41 +63,32 @@ jobs:
7363
python -m pip install jinja2
7464
python -m pip install "xinference[doc]"
7565
76-
- name: Run gen_docs.py if present
66+
- name: Run gen_docs.py (from base branch ONLY)
7767
if: steps.decide.outputs.run == 'true'
78-
working-directory: pr
7968
run: |
8069
echo "[Debug] CWD: $(pwd)"
81-
echo "[Debug] List ../main:"
82-
ls -la ../main || true
83-
echo "[Debug] List ../main/doc/source:"
84-
ls -la ../main/doc/source || true
8570
86-
# Use PR branch's gen_docs.py if it exists, otherwise use main branch's
87-
if [ -f "doc/source/gen_docs.py" ]; then
88-
echo "Using PR branch's doc/source/gen_docs.py"
89-
echo "Running pr/doc/source/gen_docs.py from its directory"
90-
(cd doc/source && python -u gen_docs.py)
91-
elif [ -f "../main/doc/source/gen_docs.py" ]; then
92-
echo "Copying main/doc/source/gen_docs.py into PR workspace"
93-
mkdir -p doc/source
94-
cp -f ../main/doc/source/gen_docs.py doc/source/gen_docs.py
95-
echo "Running pr/doc/source/gen_docs.py from its directory"
96-
(cd doc/source && python -u gen_docs.py)
97-
elif [ -f "gen_docs.py" ]; then
98-
echo "Using PR branch's gen_docs.py"
99-
echo "Running pr/gen_docs.py"
100-
python -u gen_docs.py
101-
elif [ -f "../main/gen_docs.py" ]; then
102-
echo "Copying main/gen_docs.py into PR workspace"
103-
cp -f ../main/gen_docs.py gen_docs.py
104-
echo "Running pr/gen_docs.py"
105-
python -u gen_docs.py
71+
# IMPORTANT: Only execute gen_docs.py from base branch (trusted)
72+
# We use PR's data files but base branch's code and templates
73+
if [ -f "base/doc/source/gen_docs.py" ]; then
74+
echo "Running gen_docs.py from base branch on PR data"
75+
cd pr
76+
# Copy templates from base (they should be in the same relative location)
77+
if [ -d "../base/doc/source/templates" ]; then
78+
mkdir -p doc/source
79+
cp -r ../base/doc/source/templates doc/source/
80+
fi
81+
# Execute gen_docs.py from base branch
82+
python ../base/doc/source/gen_docs.py
83+
elif [ -f "base/gen_docs.py" ]; then
84+
echo "Running gen_docs.py from base root"
85+
cd pr
86+
python ../base/gen_docs.py
10687
else
107-
echo "gen_docs.py not found in main repository, skipping."
88+
echo "gen_docs.py not found in base branch, skipping."
10889
fi
10990
110-
- name: Stage and commit changes back to PR branch
91+
- name: Stage and commit changes
11192
if: steps.decide.outputs.run == 'true'
11293
working-directory: pr
11394
run: |
@@ -129,32 +110,27 @@ jobs:
129110
echo "No changes to commit."
130111
fi
131112
132-
- name: Push back for same-repo PR
113+
- name: Push to same-repo PR
133114
env:
134-
BRANCH: ${{ github.event.pull_request.head.ref }}
115+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
135116
if: steps.decide.outputs.run == 'true' && github.event.pull_request.head.repo.full_name == github.repository
136117
working-directory: pr
137118
run: |
138119
echo "Pushing changes to same-repo PR..."
139-
git push origin HEAD:$BRANCH || echo "No changes to push."
120+
git push origin HEAD:${{ github.event.pull_request.head.ref }} || echo "No changes to push."
140121
141-
- name: Push back for fork PR using maintainer PAT
142-
if: steps.decide.outputs.run == 'true' && github.event.pull_request.head.repo.full_name != github.repository && github.event.pull_request.maintainer_can_modify
122+
- name: Push to fork PR
143123
env:
144124
PUSH_TOKEN: ${{ secrets.PUSH_TOKEN }}
145-
BRANCH: ${{ github.event.pull_request.head.ref }}
146-
HEAD_FULL_NAME: ${{ github.event.pull_request.head.repo.full_name }}
125+
if: steps.decide.outputs.run == 'true' && github.event.pull_request.head.repo.full_name != github.repository
147126
working-directory: pr
148127
run: |
149128
if [ -z "$PUSH_TOKEN" ]; then
150129
echo "Missing secrets.PUSH_TOKEN; cannot push to fork. Skipping push."
130+
echo "Please ask maintainer to run gen_docs.py manually."
151131
exit 0
152132
fi
153-
echo "Pushing changes to fork PR using maintainer PAT..."
154-
git remote set-url origin "https://x-access-token:${PUSH_TOKEN}@github.com/${HEAD_FULL_NAME}.git"
155-
git push origin HEAD:$BRANCH || echo "No changes to push."
156-
157-
- name: Skip push for fork PR without maintainer edit permission
158-
if: steps.decide.outputs.run != 'true' && github.event.pull_request.head.repo.full_name != github.repository && !github.event.pull_request.maintainer_can_modify
159-
run: |
160-
echo "Fork PR does not allow edits by maintainers; run succeeded but skip pushing commits."
133+
echo "Pushing changes to fork PR..."
134+
# Set remote for fork repository
135+
git remote add fork "https://x-access-token:${PUSH_TOKEN}@github.com/${{ github.event.pull_request.head.repo.full_name }}.git"
136+
git push fork HEAD:${{ github.event.pull_request.head.ref }} || echo "No changes to push."

0 commit comments

Comments
 (0)