From 6f0ab669cf8ca8efdcd805b9f4e135fdf31124ec Mon Sep 17 00:00:00 2001 From: Federico Grandi Date: Wed, 19 Aug 2026 01:03:07 +0200 Subject: [PATCH] docs: highlight untrusted git-arg interpolation as a warning callout Co-authored-by: Cursor --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9918d141..a9501598 100644 --- a/README.md +++ b/README.md @@ -125,8 +125,10 @@ Git child processes are also limited to the `https`, `http`, `ssh`, `file`, and Message-from-file flags (`-F`, `--file`, abbreviations such as `--fi`, and short-option clusters that include `F` such as `-aF`) are rejected: they can embed arbitrary runner filesystem contents into a tag or commit message and, with a push, into the repository history. Pathspec-from-file flags (`--pathspec-from-file`, `--pathspec-file-nul`, and abbreviations such as `--pathspec-fr` / `--pathspec-fi`) are rejected on `add`, `remove`, and `commit`: they can read an arbitrary runner file and leak its contents into the action log. Unmatched `'` / `"` quotes are also rejected: `string-argv` can otherwise split on an odd quote and turn part of a value into extra flags (for example a branch name like `fix'--force` becoming `fix` plus `--force`). -A quoted segment is accepted only when its closing quote is followed by whitespace or the end of the input. That is a conservative argument-boundary check, not a claim that every rejected form would become extra argv words: `'main'--force` is rejected (and would split into `main` plus `--force`), and so is `a'b'c` (which `string-argv` would keep as one token). `--message='hello'` is allowed because the closer is at the end of the word. Put a space after a wrapping closer (`origin 'main' --force`) or omit the quotes. -Do not interpolate untrusted data (for example values from `github.event.*`, `github.head_ref`, or repository content that contributors can edit) into `fetch`, `pull`, `push`, `tag`, `tag_push`, or `commit` without sanitizing them first. When the branch name is dynamic, prefer the default `push: true` with [`new_branch`](#creating-a-new-branch) instead of embedding the ref in a custom `push` string. +A quoted segment is accepted only when its closing quote is followed by whitespace or the end of the input. That is a conservative argument-boundary check, not a claim that every rejected form would become extra argv words: `'main'--force` is rejected (and would split into `main` plus `--force`), and so is `a'b'c` (which `string-argv` would keep as one token). `--message='hello'` is allowed because the closer is at the end of the word. Put a space after a wrapping closer (`origin 'main' --force`) or omit the quotes. + +> [!WARNING] +> Do not interpolate untrusted data (for example values from `github.event.*`, `github.head_ref`, or repository content that contributors can edit) into `fetch`, `pull`, `push`, `tag`, `tag_push`, or `commit` without sanitizing them first. When the branch name is dynamic, prefer the default `push: true` with [`new_branch`](#creating-a-new-branch) instead of embedding the ref in a custom `push` string. ### Allow unsafe git protocols