From 4f6aab9502deb230cc81f4623797342fc9ba4ba8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Feb 2026 22:10:12 +0000 Subject: [PATCH 1/2] Initial plan From 157d3f5377d0799349febab1954d1e28137d4636 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Feb 2026 22:24:12 +0000 Subject: [PATCH 2/2] security: replace extra-args denylist with allowlist in setup-python-env action Co-authored-by: pmalarme <686568+pmalarme@users.noreply.github.com> --- .github/actions/setup-python-env/README.md | 22 ++++++++++++--------- .github/actions/setup-python-env/action.yml | 22 ++++++++++++--------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/.github/actions/setup-python-env/README.md b/.github/actions/setup-python-env/README.md index 695228b..0bd8a37 100644 --- a/.github/actions/setup-python-env/README.md +++ b/.github/actions/setup-python-env/README.md @@ -18,15 +18,19 @@ and `extra-args` extend it. `extra-args` is passed to `uv sync` via an environment variable and intentionally word-split so that callers can supply multiple flags (e.g. -`--all-packages --prerelease=if-necessary-or-explicit`). A defensive guard -validates each token before execution: every token must start with `-` and -contain only alphanumeric characters and safe flag characters (`=`, `.`, `:`, -`/`, `@`, `+`, `-`). Tokens that do not match this pattern cause the action to -fail immediately with an error. Despite this guard, **only hardcoded, static -strings should be used**. Never pass dynamic values sourced from issue bodies, -PR descriptions, user-controlled inputs, or any other external source, as those -could introduce unexpected `uv sync` flags and alter environment resolution -behaviour. +`--all-packages --prerelease=if-necessary-or-explicit`). A strict **allowlist** +guard validates each token before execution: only the following flags are +permitted: + +- `--all-packages` +- `--prerelease=if-necessary-or-explicit` +- `-U` +- `--upgrade` + +Any token not on this list causes the action to fail immediately with an error. +Despite this guard, **only hardcoded, static strings should be used**. Never +pass dynamic values sourced from issue bodies, PR descriptions, user-controlled +inputs, or any other external source. ## Usage diff --git a/.github/actions/setup-python-env/action.yml b/.github/actions/setup-python-env/action.yml index 9455985..687f3ba 100644 --- a/.github/actions/setup-python-env/action.yml +++ b/.github/actions/setup-python-env/action.yml @@ -35,16 +35,20 @@ runs: args="$args --group docs" fi if [[ -n "$EXTRA_ARGS" ]]; then - # Validate each whitespace-split token: must start with '-' and contain only safe flag characters. - # NOTE: '--' (end-of-options marker) is intentionally allowed; positional args would fail validation. + # Allowlist: only explicitly permitted uv sync flags are accepted. + allowed_args=( + "--all-packages" + "--prerelease=if-necessary-or-explicit" + "-U" + "--upgrade" + ) for arg in $EXTRA_ARGS; do - # Denylist: block flags that could redirect dependency resolution to an attacker-controlled index. - if [[ "$arg" =~ ^--(index-url|extra-index-url|trusted-host|find-links)(=|$) ]]; then - echo "::error::Blocked dangerous extra-args token: '$arg'. Registry overrides are not permitted." >&2 - exit 1 - fi - if [[ ! "$arg" =~ ^-[a-zA-Z0-9=._:/@+-]+$ ]]; then - echo "::error::Unsafe extra-args token: '$arg'. Each token must start with '-' and contain only safe flag characters." >&2 + allowed=false + for a in "${allowed_args[@]}"; do + [[ "$arg" == "$a" ]] && allowed=true && break + done + if [[ "$allowed" != "true" ]]; then + echo "::error::Unrecognized extra-args token: '$arg'. Only the following flags are permitted: ${allowed_args[*]}." >&2 exit 1 fi done