Skip to content

Commit ef09b88

Browse files
authored
Document safe handling of file list outputs in workflows (#326)
Recommend passing *_files values through env: instead of interpolating them directly into run: scripts, and update README examples and CI workflows to follow that pattern. Credits: https://github.com/tjswlsgg
1 parent 44adc5b commit ef09b88

2 files changed

Lines changed: 24 additions & 6 deletions

File tree

‎.github/workflows/pull-request-verification.yml‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ jobs:
193193
excludesOnly:
194194
- '!**/*.md'
195195
- name: Print 'mobile_files'
196-
run: echo ${{steps.filter.outputs.mobile_files}}
196+
env:
197+
MOBILE_FILES: ${{ steps.filter.outputs.mobile_files }}
198+
run: echo "$MOBILE_FILES"
197199
- name: filter-test
198200
if: |
199201
steps.filter.outputs.mobile != 'true'
@@ -227,11 +229,17 @@ jobs:
227229
any:
228230
- added|deleted|modified: "*"
229231
- name: Print 'added_files'
230-
run: echo ${{steps.filter.outputs.added_files}}
232+
env:
233+
ADDED_FILES: ${{ steps.filter.outputs.added_files }}
234+
run: echo "$ADDED_FILES"
231235
- name: Print 'modified_files'
232-
run: echo ${{steps.filter.outputs.modified_files}}
236+
env:
237+
MODIFIED_FILES: ${{ steps.filter.outputs.modified_files }}
238+
run: echo "$MODIFIED_FILES"
233239
- name: Print 'deleted_files'
234-
run: echo ${{steps.filter.outputs.deleted_files}}
240+
env:
241+
DELETED_FILES: ${{ steps.filter.outputs.deleted_files }}
242+
run: echo "$DELETED_FILES"
235243
- name: filter-test
236244
if: |
237245
steps.filter.outputs.added != 'true'

‎README.md‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ For more scenarios see [examples](#examples) section.
6767
6868
## Notes
6969
70+
- **Security:** `${FILTER_NAME}_files` outputs contain filenames that may be attacker-influenced on pull requests.
71+
Do not interpolate them directly into a `run:` script with `${{ ... }}`.
72+
Pass the value through `env:` and reference the variable from the shell instead.
73+
See [Custom processing of changed files](#custom-processing-of-changed-files).
7074
- Paths expressions are evaluated using [picomatch](https://github.com/micromatch/picomatch) library.
7175
Documentation for path expression format can be found on the project GitHub page.
7276
- Picomatch [dot](https://github.com/micromatch/picomatch#options) option is set to true.
@@ -205,7 +209,7 @@ For more information, see [CHANGELOG](https://github.com/dorny/paths-filter/blob
205209
- `'true'` - if **any** changed file matches **at least one** of the filter's rules and **none** of its negated rules
206210
- `'false'` - if **no** changed file matches **at least one** of the filter's rules and **none** of its negated rules
207211
- Each filter sets an output variable with the name `${FILTER_NAME}_count` to the count of matching files.
208-
- If enabled, for each filter it sets an output variable with the name `${FILTER_NAME}_files`. It will contain a list of all files matching the filter.
212+
- If enabled, for each filter it sets an output variable with the name `${FILTER_NAME}_files`. It will contain a list of all files matching the filter. Treat these values as untrusted when filenames can come from pull requests.
209213
- `changes` - JSON array with names of all filters matching any of the changed files.
210214

211215
## Examples
@@ -589,9 +593,13 @@ jobs:
589593
- added|modified: '*.md'
590594
- name: Lint Markdown
591595
if: ${{ steps.filter.outputs.markdown == 'true' }}
592-
run: npx textlint ${{ steps.filter.outputs.markdown_files }}
596+
env:
597+
MARKDOWN_FILES: ${{ steps.filter.outputs.markdown_files }}
598+
run: npx textlint $MARKDOWN_FILES
593599
```
594600
601+
When passing file lists to shell commands, use `env:` as shown above. Do not write `${{ steps.filter.outputs.markdown_files }}` directly inside the `run:` script.
602+
595603
</details>
596604

597605
<details>
@@ -617,6 +625,8 @@ jobs:
617625
files: ${{ steps.filter.outputs.changed_files }}
618626
```
619627
628+
The `json` and `csv` formats are intended as structured data for scripts, programs, or other actions. Passing them to an action input as above is fine. Do not interpolate `json` or `csv` outputs directly into a `run:` script.
629+
620630
</details>
621631

622632
## See also

0 commit comments

Comments
 (0)