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:
- Add a helper function
validateTargetRepo(targetRepo) (or reuse an existing one from the codebase) that checks targetRepo against an allowlist.
- The allowlist should default to
[context.repo.owner + '/' + context.repo.repo] (same-repo only) unless explicitly expanded via a configuration environment variable.
- Call
validateTargetRepo(targetRepo) before constructing repoUrl at line ~105.
- If validation fails, call
core.setFailed(...) with a clear error message and return early.
- 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 · ◷
Conformance Check Failure
Check ID: SEC-005
Severity: HIGH
Category: Security
Problem Description
The handler
actions/setup/js/push_experiment_state.cjsreferences atargetRepovalue and constructs authenticated HTTPS URLs to push experiment state to a git branch. However, it does not validatetargetRepoagainst 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
actions/setup/js/push_experiment_state.cjs🔍 Current vs Expected Behavior
Current Behavior
In
main()(line ~85):targetRepois derived fromcontext.repo(which comes fromGITHUB_REPOSITORY), but there is no call toallowedRepos,validateTargetRepo, orcheckAllowedRepobefore using it to construct the authenticated push URL (line ~105) andgit 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:
validateTargetRepo(targetRepo)(or reuse an existing one from the codebase) that checkstargetRepoagainst an allowlist.[context.repo.owner + '/' + context.repo.repo](same-repo only) unless explicitly expanded via a configuration environment variable.validateTargetRepo(targetRepo)before constructingrepoUrlat line ~105.core.setFailed(...)with a clear error message and return early.@safe-outputs-exempt SEC-005JSDoc 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-suppliedtarget-repoparameter.Verification
After remediation, verify the fix by running:
The check
SEC-005should pass without errors.References
docs/src/content/docs/reference/safe-outputs-specification.mdscripts/check-safe-outputs-conformance.sh