Skip to content

[Safe Outputs Conformance] SEC-005: update_activation_comment.cjs supports target-repo but lacks allowlist check #36079

@github-actions

Description

@github-actions

Conformance Check Failure

Check ID: SEC-005 (Cross-Repository Validation)
Severity: HIGH
Category: Security

Problem Description

The update_activation_comment.cjs handler accepts a caller-supplied options.targetRepo value ("owner/repo") and uses it to create a fallback comment in that repository, but it does not validate the target repository against a configured allowlist. SEC-005 requires that any safe-output handler supporting cross-repository writes validate the target repo against an allowlist before performing the API call, to prevent a workflow from being steered into writing comments to arbitrary repositories.

Every other cross-repo handler in actions/setup/js/ (e.g. add_comment.cjs, add_labels.cjs, assign_milestone.cjs) already routes its target-repo resolution through the canonical allowlist helpers in repo_helpers.cjs. This handler is the outlier.

Affected Components

  • Files: actions/setup/js/update_activation_comment.cjs
  • Handlers: update_activation_comment (cross-repo fallback comment path)
  • Canonical helpers: actions/setup/js/repo_helpers.cjs (resolveTargetRepoConfig, resolveAndValidateRepo)
🔍 Current vs Expected Behavior

Current Behavior

In the standard-mode fallback path (update_activation_comment.cjs, around lines 194-210), options.targetRepo is split into fallbackOwner/fallbackRepo and passed straight to the GitHub API:

if (options.targetRepo) {
  const parts = options.targetRepo.split("/");
  if (parts.length === 2) {
    fallbackOwner = parts[0];
    fallbackRepo = parts[1];
  }
}
const fallbackClient = options.targetGithubClient || github;
// ...
await fallbackClient.request("POST /repos/{owner}/{repo}/issues/{issue_number}/comments", {
  owner: fallbackOwner,
  repo: fallbackRepo,
  // ...
});

There is no check that fallbackOwner/fallbackRepo is an allowed target before the write.

Expected Behavior

SEC-005 requires the handler to either:

  1. Validate targetRepo against the configured allowlist (allowedRepos) using the shared helpers before issuing the API call, matching the pattern in add_comment.cjs; or
  2. If this handler is genuinely exempt because targetRepo/targetGithubClient are always derived internally from already-validated context (never from agent-controlled output), document that with a @safe-outputs-exempt SEC-005 annotation and a justification comment.

Remediation Steps

This task can be assigned to a Copilot coding agent:

  1. Review the cross-repo fallback path in actions/setup/js/update_activation_comment.cjs (the if (options.targetRepo) block) and determine the provenance of options.targetRepo — is it ever derived from agent-controlled safe output, or is it always supplied internally from validated invocation context?
  2. If it can carry agent-influenced values: import resolveTargetRepoConfig and resolveAndValidateRepo from repo_helpers.cjs and validate targetRepo against allowedRepos before the POST .../comments request, mirroring add_comment.cjs (see lines 378-452 there). Reject or fall back safely when the repo is not allowed.
  3. If it is genuinely internal-only: add a top-of-file @safe-outputs-exempt SEC-005 annotation with a one-line justification explaining why allowlist validation is unnecessary (so the checker skips it intentionally rather than silently).
  4. Add or extend a unit test asserting that an out-of-allowlist targetRepo is rejected (or that the exemption invariant holds).

Verification

After remediation, verify the fix by running:

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

The SEC-005 check should pass: [PASS] SEC-005: All cross-repo handlers validate allowlists.

References

  • Safe Outputs Specification: docs/src/content/docs/reference/safe-outputs-specification.md
  • Conformance Checker: scripts/check-safe-outputs-conformance.sh (SEC-005, lines 165-193)
  • Canonical allowlist helpers: actions/setup/js/repo_helpers.cjs
  • Reference implementation: actions/setup/js/add_comment.cjs
  • Run ID: 26705913294
  • Date: 2026-05-31

Generated by ✅ Daily Safe Outputs Conformance Checker · opus48 526.1K ·

  • expires on Jun 1, 2026, 7:02 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