Skip to content

[Safe Outputs Conformance] SEC-005: push_experiment_state.cjs supports target-repo without allowlist validation #30086

@github-actions

Description

@github-actions

Conformance Check Failure

Check ID: SEC-005
Severity: HIGH
Category: Security

Problem Description

The handler actions/setup/js/push_experiment_state.cjs references a targetRepo value and constructs authenticated HTTPS URLs to push experiment state to a git branch. However, it does not validate targetRepo against an allowlist before using it for cross-repository operations.

Without an allowlist check, a malicious actor who can influence environment variables could redirect the push to an unintended repository, potentially leaking experiment state data or performing unauthorized writes.

Affected Components

  • Files: actions/setup/js/push_experiment_state.cjs
🔍 Current vs Expected Behavior

Current Behavior

In main() (line ~85):

const targetRepo = `${context.repo.owner}/${context.repo.repo}`;
const repoUrl = `(xaccesstoken/redacted):${ghToken}@${serverHost}/${targetRepo}.git`;

targetRepo is derived from context.repo (which comes from GITHUB_REPOSITORY), but there is no call to allowedRepos, validateTargetRepo, or checkAllowedRepo before using it to construct the authenticated push URL (line ~105) and git remote set-url (line ~153).

Expected Behavior

The specification requires that any handler supporting cross-repository operations validate the target repository against a configured allowlist before proceeding. This prevents token exfiltration or unauthorized cross-repo pushes.

Remediation Steps

This task can be assigned to a Copilot coding agent with the following steps:

  1. Add a helper function validateTargetRepo(targetRepo) (or reuse an existing one from the codebase) that checks targetRepo against an allowlist.
  2. The allowlist should default to [context.repo.owner + '/' + context.repo.repo] (same-repo only) unless explicitly expanded via a configuration environment variable.
  3. Call validateTargetRepo(targetRepo) before constructing repoUrl at line ~105.
  4. If validation fails, call core.setFailed(...) with a clear error message and return early.
  5. Alternatively, add a @safe-outputs-exempt SEC-005 JSDoc annotation if cross-repo is intentionally disabled by design and this is a false positive — but only after confirming the handler never reads a caller-supplied target-repo parameter.

Verification

After remediation, verify the fix by running:

bash scripts/check-safe-outputs-conformance.sh

The check SEC-005 should pass without errors.

References

  • Safe Outputs Specification: docs/src/content/docs/reference/safe-outputs-specification.md
  • Conformance Checker: scripts/check-safe-outputs-conformance.sh
  • Run ID: §25304551554
  • Date: 2026-05-04

Generated by Daily Safe Outputs Conformance Checker · ● 123.4K ·

  • expires on May 5, 2026, 6:36 AM UTC

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions