Skip to content

CodeQL scan-dispatch repository gate accepts non-canonical trailing-dot and embedded-dotdot targets #2264

Description

@seonghobae

Problem

Protected main@64aa08d7fa487deacd41c761c36277ca68cab6c9 still validates TARGET_REPOSITORY in .github/workflows/codeql-scan-dispatch.yml with:

[[ "$TARGET_REPOSITORY" =~ ^ContextualWisdomLab/[A-Za-z0-9_.-]+$ ]]

That organization-membership check accepts non-canonical repository slugs such as ContextualWisdomLab/repository. and ContextualWisdomLab/repo..name.

The same protected owner now rejects embedded .. and trailing . components in the scheduler/source-fix repository-identity contract. The CodeQL dispatch trust boundary is therefore looser than the canonical repository identity used by its producer/coordination plane.

This is independent of the queue-health parser drift tracked separately in #2263: both are consumers of repository identity, but CodeQL scan dispatch is a security-sensitive repository_dispatch admission path.

RED

Add contract coverage that exercises the actual workflow admission expression for at least:

  • ContextualWisdomLab/repository. → reject
  • ContextualWisdomLab/repo..name → reject
  • ContextualWisdomLab/.. → reject
  • ContextualWisdomLab/. → reject
  • a valid dotted/hyphenated repository name → accept

Do not test only a replacement regex detached from the workflow text.

Minimum causal fix

Align the workflow target-repository gate with the current canonical invariant: retain the ContextualWisdomLab/ owner restriction and allowed slug characters, but reject any repository component containing .. or ending in ..

Preserve the existing actor+sender authorization, v1/v2 protocol binding, exact PR head/base validation, producer-source binding, matrix/rerun validation, credential boundary, and fail-closed semantics.

If a reusable/versioned repository-identity helper can be consumed by workflow admission without introducing a mutable runtime dependency, prefer that; otherwise pin the invariant with workflow contract tests to prevent another drift.

Acceptance

  • hostile target repository cases are RED against current protected production workflow;
  • minimum admission fix makes them GREEN without changing valid dispatch behavior;
  • existing CodeQL dispatch protocol/security contracts remain GREEN on the exact head;
  • no manual dispatch, synthetic status, gate weakening, or leaf-workflow copy is introduced;
  • downstream/stale branches adopt the repaired protected slice path-wise rather than copying this pre-fix workflow wholesale.

Activity

  1. seonghobae commented on Sep 18, 2026

    @seonghobae
    ContributorAuthor

    Real production-path RED is now materialized as Draft PR #2271 at exact head 10a87abddddd0b7b02d4c10b4ee9347ebe6f2237. It adds only tests/test_codeql_scan_dispatch_repository_identity_contract.py (+59/-0) on protected main@64aa08d7... and reuses the existing _run_validate_step() harness, which extracts and executes the actual Bind workflow inputs to live organization pull request metadata shell block. Hostile cases cover trailing ., embedded .., exact . and exact ..; positive cases retain dotted/hyphenated valid slugs. The follow-up test commit also pins the existing PR metadata validation rejected... diagnostic so a later unrelated failure cannot masquerade as repository-identity rejection. Production workflow is intentionally unchanged, so this remains RED pending the minimum admission hunk and fresh exact-head checks.

  2. seonghobae commented on Sep 18, 2026

    @seonghobae
    ContributorAuthor

    Implementation lane #2271 has advanced from RED-only to the minimum production repair at exact head 2b849c874122961e025c29f7fa0bb697863c3d68. The accepted candidate was preflighted before ref movement and compares against 10a87abddddd0b7b02d4c10b4ee9347ebe6f2237 as ahead 1 / behind 0, exactly one workflow file, +2/-0. The existing fixed ContextualWisdomLab/ owner/character grammar is preserved; the target repository component now fails closed when it contains .. or ends in .. Two earlier unreferenced reconstruction candidates exposed unrelated one-line collateral during preflight and were discarded; neither was ever pushed. Branch movement used force=false. Exact-head COMMENT review is #2271 review 5248619036. Fresh CodeQL/SAST/Python Security/Security Scan runs are queued, so keep this issue open until focused workflow-contract tests, hosted checks, and qualifying independent review are terminal.

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