Skip to content

[Safe Outputs Conformance] SEC-002: load_experiment_state_from_repo.cjs makes API call before content validation #30955

@github-actions

Description

@github-actions

Conformance Check Failure

Check ID: SEC-002
Severity: CRITICAL
Category: Security

Problem Description

The load_experiment_state_from_repo.cjs handler invokes the GitHub API (octokit.rest.repos.getContent) to fetch remote content before performing size and structure validation on the returned data. The Safe Outputs Specification requires that all input validation occur before any API calls to prevent processing of oversized or malformed payloads that could trigger downstream issues.

The conformance checker's AWK rule confirms that no validate, sanitize, or enforceLimit keyword appears in the file prior to the octokit. call.

Affected Components

  • File: actions/setup/js/load_experiment_state_from_repo.cjs
  • Function: main() — calls fetchFileFromBranch(octokit, ...) then checkLimit(content, MAX_STATE_FILE_BYTES) after the response is received
🔍 Current vs Expected Behavior

Current Behavior

main()
  → fetchFileFromBranch(octokit, ...)   ← API call first
      → octokit.rest.repos.getContent()
  → checkLimit(content, MAX_STATE_FILE_BYTES)  ← validation after
  → JSON.parse(content)                        ← structure check after

Input parameters (branch name, file path) are validated via env-var guards before the API call, but the response content is not validated until after it has been fetched.

Expected Behavior

All validation of inputs that influence the API call scope (e.g., branch name format, allowed characters) and any pre-fetch guards must appear before the octokit.* invocation. Post-fetch content validation (checkLimit, JSON.parse) should remain after the call but the ordering should be explicit and the pre-call guard surface should be complete.

The simplest fix is to add a clearly named validation function (e.g., validateInputs) that runs before fetchFileFromBranch, so the conformance check can detect it:

function validateInputs(branch, owner, repo) {
  if (!branch || typeof branch !== 'string') throw new Error('Invalid branch');
  if (!owner || !repo) throw new Error('Invalid repository');
  // add any further sanitization here
}
// ...
validateInputs(branch, owner, repo);   // ← before API call
content = await fetchFileFromBranch(octokit, owner, repo, branch, stateFileName);

Remediation Steps

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

  1. Open actions/setup/js/load_experiment_state_from_repo.cjs.
  2. Add a validateInputs(branch, owner, repo) function that checks that branch is a non-empty string matching the allowed branch-name pattern and that owner/repo are non-empty strings.
  3. Call validateInputs(branch, owner, repo) inside main() before the call to fetchFileFromBranch.
  4. Ensure the function name contains one of the keywords validate, sanitize, or enforceLimit so the conformance checker can detect it.
  5. Run the conformance checker to confirm SEC-002 passes.

Verification

After remediation, verify the fix by running:

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

The check SEC-002 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: §25540182126
  • Date: 2026-05-08

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

  • expires on May 9, 2026, 6:17 AM UTC

Metadata

Metadata

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