mirror of
https://github.com/ai-robots-txt/ai.robots.txt.git
synced 2026-08-31 05:14:06 +02:00
`git commit -m "${{ github.event.head_commit.message }}"` splices arbitrary text
straight into a double-quoted bash string. A message containing a double quote
closes the string early and the remainder is re-parsed as shell words.
This is what broke main after #248 merged. That PR's title contained
"Unclear at this time." (with quotes), so the merge commit message did too, and
the line bash actually ran was:
git commit -m "Fill "Unclear at this time." from primary operator docs ..."
which git received as:
-m "Fill Unclear" at this "time. from primary operator docs ..."
Hence `error: pathspec 'at' did not match any file(s) known to git`, a failed
run, and the revert in 80c19fc. The data in that PR was fine — robots.py
--convert exits 0 against it and code/tests.py passes 13/13.
The same interpolation is also a script-injection vector, which is the more
important reason to change it: a PR title is attacker-controlled, and
chore: tidy"; <any command>; echo "
executes that command on the runner with the workflow's token. `inputs.message`
has the same shape in the `if [ -n ... ]` test and its own `git commit -m`, so
all three are moved.
Passing through `env:` and quoting the shell variable is GitHub's documented
recommendation for untrusted values. The variable is expanded by bash after
parsing, so quotes, newlines and `$(...)` stay literal text.
Verified: code/tests.py 13/13 · python code/robots.py --convert exits 0 and
leaves robots.txt, table-of-bot-metrics.md and every server-config output
byte-identical · reproduced both the parse failure and the injection locally
against the old form, and confirmed the env form commits the same message
verbatim, quotes included.
51 lines
1.5 KiB
YAML
51 lines
1.5 KiB
YAML
on:
|
|
workflow_call:
|
|
inputs:
|
|
message:
|
|
type: string
|
|
required: true
|
|
description: The message to commit
|
|
push:
|
|
paths:
|
|
- 'robots.json'
|
|
- '.github/workflows/**'
|
|
- 'code/**'
|
|
branches:
|
|
- "main"
|
|
|
|
jobs:
|
|
ai-robots-txt:
|
|
runs-on: ubuntu-latest
|
|
name: ai-robots-txt
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 2
|
|
- env:
|
|
INPUT_MESSAGE: ${{ inputs.message }}
|
|
HEAD_COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
|
|
run: |
|
|
pip install beautifulsoup4
|
|
git config --global user.name "ai.robots.txt"
|
|
git config --global user.email "ai.robots.txt@users.noreply.github.com"
|
|
git log -1
|
|
git status
|
|
echo "Updating robots.txt and table-of-bot-metrics.md if necessary ..."
|
|
python code/robots.py --convert
|
|
echo "... done."
|
|
git --no-pager diff
|
|
git add -A
|
|
if [ -z "$(git diff --staged)" ]; then
|
|
# To have the action run successfully, if no changes are staged, we
|
|
# manually skip the later commits because they fail with exit code 1
|
|
# and this would then display as a failure for the Action.
|
|
echo "No staged changes to commit. Skipping commit and push."
|
|
exit 0
|
|
fi
|
|
if [ -n "$INPUT_MESSAGE" ]; then
|
|
git commit -m "$INPUT_MESSAGE"
|
|
else
|
|
git commit -m "$HEAD_COMMIT_MESSAGE"
|
|
fi
|
|
git push
|
|
shell: bash
|