Skip to content

Queue-health repository identity accepts embedded .. and trailing-dot slugs #2263

Open

Description

@seonghobae

Problem

Protected main@64aa08d7fa487deacd41c761c36277ca68cab6c9 has a repository-identity inconsistency in scripts/ci/actions_queue_health_core.py.

REPOSITORY_PATTERN currently accepts any [A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+, while _repository_name() only rejects path segments exactly equal to . or ... As a result, traversal-adjacent/non-canonical identifiers such as ContextualWisdomLab/repository., ContextualWisdomLab/repo..name, ContextualWisdomLab./repository, and Contextual..WisdomLab/repository are admitted.

This matters because the queue-health collector consumes a reviewed repository allowlist and uses the validated owner/repository identity to perform cross-repository Actions reads. The read-only boundary should enforce the intended component invariant symmetrically on owner and repository names.

Do not treat the current protected scheduler regex as complete authority for this issue. Its generic full-name expression still misses an owner component ending in . before the slash; scheduler reconciliation remains separately owned by #2040. Source-fix paths use a narrower organization-local repository-name grammar and likewise are not a generic full-name validator for queue health.

Canonical implementation lane: #2268.

RED

Exercise the production path through load_allowlist() for at least:

  • ContextualWisdomLab/repository.
  • ContextualWisdomLab/repo..name
  • ContextualWisdomLab./repository
  • Contextual..WisdomLab/repository
  • ContextualWisdomLab/..
  • ContextualWisdomLab/.

The first four currently pass the production parser; all six must fail closed after repair.

The positive contract must also prove that legitimate names remain admissible, including:

  • ContextualWisdomLab/.github
  • ContextualWisdomLab/repository.name
  • ContextualWisdomLab/repository_name
  • ContextualWisdomLab/repository-name

Minimum causal fix

Retain the existing one-slash and allowed-character grammar, then validate both owner and repository components symmetrically: reject a component when it contains .. or ends in ., while preserving a leading single dot such as .github and ordinary interior single dots.

Prefer a shared/versioned validation helper only if one already owns exactly this generic component contract and can be consumed without introducing a mutable cross-module dependency. Otherwise keep the implementation local and pin both hostile and valid cases so future owner/repository validators cannot drift silently.

Do not weaken or disable queue-health, reduce its repository coverage, or treat malformed identities as skipped-success evidence.

Acceptance

  • hostile identity RED is demonstrated against the pre-fix production parser;
  • valid punctuation-bearing repository identities remain accepted;
  • minimum production fix makes the complete identity suite GREEN;
  • existing explicit allowlist and read-only/pinned workflow contract remain GREEN;
  • exact-head security/quality checks complete normally;
  • any adoption into stale scheduler/reconciliation branches is path-wise and does not copy the pre-fix queue-health slice.

Activity

  1. seonghobae commented on Sep 18, 2026

    @seonghobae
    ContributorAuthor

    Concrete owner RED is now in Draft PR #2268 at exact head 385923f0818be44107322ac1c36ee2663c2c1468. The new regression goes through production load_allowlist() and covers trailing-dot plus embedded-.. repository components while retaining the existing ./.. traversal cases. Production remains intentionally unchanged until the minimum parser hunk can be applied without a complete-file rewrite; #2268 is not GREEN or a successor claim yet.

  2. seonghobae commented on Sep 18, 2026

    @seonghobae
    ContributorAuthor

    RED lane update: #2268 advanced to d43c83554581b548003f8a824e54207193e5397f. Review of predecessor 385923f... found the same non-canonical admission on the owner side, not just the repository-name side: current _repository_name() also accepts ContextualWisdomLab./repository and Contextual..WisdomLab/repository. The production-path load_allowlist() regression now covers those two witnesses in addition to repository., repo..name, .., and .. Production remains unchanged/RED; fresh exact-head security checks were naturally created and are queued. Minimum fix should validate both owner and repository components symmetrically without weakening the collector's read-only/fail-closed boundaries.

  3. seonghobae commented on Sep 18, 2026

    @seonghobae
    ContributorAuthor

    Canonical implementation lane #2268 has moved from RED-only to the minimum production repair at exact head 142e5b2617778e79f665693be1e6f8c04d7533aa. The source change is exactly one line in scripts/ci/actions_queue_health_core.py: after the existing one-slash/allowed-character grammar, both components now reject embedded .. and trailing ., preserving .github and ordinary interior single dots. Pre-move compare against c754daf... was ahead 1 / behind 0, one file, +1/-1; branch movement was a non-force fast-forward. Exact-head review: #2268 review 5248475400. Hosted Security Scan/SAST/Python Security/CodeQL runs are newly queued, so keep this issue open until the focused production-path suite, existing queue-health suite, required hosted checks, and qualifying independent review are complete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority: highHigh-priority or P1 work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions