Problem
The doc gates print tracked file names inside their findings. The GitHub Actions runner treats a stdout line as a workflow command when it begins with :: once leading whitespace is trimmed, so the indent in front of each finding does not protect it. The runner's ActionCommand.cs trims the message before checking for the command key.
Suppose a pull request tracks a file whose name starts with :: and that file raises a finding. The gate then prints a line the runner executes as a command. That can create an error annotation with a title and text the author chose, turn off command processing for the rest of the step with ::stop-commands::, or mask arbitrary strings with ::add-mask::. A fork pull request controls both the file name and .gitattributes, so it can reach this.
Evidence
This case is constructed. Track a shebang file named ::error title=forged::all checks passed under * text=auto eol=crlf. repo_gate.py --check eol-coverage then prints ::error title=forged::all checks passed: tracked shebang path resolves to ....
This predates the change that decodes quoted names in repo_gate.py, because git never quotes : or a space. The same change added printable() to escape control characters, and that does not cover this case. prose_lint.py prints paths the same way and likely has the same exposure. That has not been checked.
Suggested fix
Neutralize a leading :: in any printed line that carries a path. Alternatively, wrap the gate's findings in a ::stop-commands:: block that uses a random token. Choosing between these is a design call for whoever takes this issue.
Problem
The doc gates print tracked file names inside their findings. The GitHub Actions runner treats a stdout line as a workflow command when it begins with
::once leading whitespace is trimmed, so the indent in front of each finding does not protect it. The runner'sActionCommand.cstrims the message before checking for the command key.Suppose a pull request tracks a file whose name starts with
::and that file raises a finding. The gate then prints a line the runner executes as a command. That can create an error annotation with a title and text the author chose, turn off command processing for the rest of the step with::stop-commands::, or mask arbitrary strings with::add-mask::. A fork pull request controls both the file name and.gitattributes, so it can reach this.Evidence
This case is constructed. Track a shebang file named
::error title=forged::all checks passedunder* text=auto eol=crlf.repo_gate.py --check eol-coveragethen prints::error title=forged::all checks passed: tracked shebang path resolves to ....This predates the change that decodes quoted names in
repo_gate.py, because git never quotes:or a space. The same change addedprintable()to escape control characters, and that does not cover this case.prose_lint.pyprints paths the same way and likely has the same exposure. That has not been checked.Suggested fix
Neutralize a leading
::in any printed line that carries a path. Alternatively, wrap the gate's findings in a::stop-commands::block that uses a random token. Choosing between these is a design call for whoever takes this issue.