Skip to content

P0: Harden shell completion executable names and debug-file handling #97

Closed

Description

@rmcdaniel

Operator disposition

This is an ordinary P0 product defect requiring an immediate fix by the CLI repo agent. It is not a CVE, GHSA, advisory, compromise claim, or external disclosure. Do not contact upstream or make a broader affected-range claim from this issue.

Confirmed scope

The exact published 2.3.5 PHP/Symfony implementation accepts its invocation basename when generating shell-completion output and uses a predictable shared temporary debug path. A deliberately unsafe local basename can therefore cross the shell-script generation boundary, and the debug path does not provide an acceptable file-type/link boundary. Normal installation and invocation as dw are unaffected. No remote trigger, customer-data access, credential access, exploitation, or incident is established.

The Rust completion port under #93 encountered the same boundary and must remain consistent, but this issue owns the fix-only PHP maintenance release.

Required correction

  • Base PHP 2.3.6 only on the immutable 2.3.5 source.
  • Refuse unsafe invocation basenames before emitting any completion script bytes, including command abbreviations that resolve to completion or _complete. Return the established invalid-input exit code.
  • Prevent completion debug behavior from opening or following a predictable shared temporary path. A maintenance-safe refusal/disable is acceptable; normal completion must remain functional.
  • Preserve ordinary dw Bash, Zsh, and Fish completion behavior.
  • Add harmless adversarial controls for crafted names and symlink/FIFO/directory/hard-link sentinels without using credentials or external commands.
  • Produce a reproducible PHAR and qualify the exact built artifact, not source tests alone.
  • Record exact source SHA, artifact SHA-256, full-suite result, any baseline-reproduced failure, and cleanup.
  • Keep the Rust Rust CLI: port completion and _complete (shell completion) #93 correction separate and preserve its history.

Ownership and gates

The CLI repo agent owns implementation and the ordinary 2.3.6 maintenance PR immediately. General retains merge/release decisions; Security reviews the exact head and built artifact. No tag, asset upload, installer/latest mutation, or public release occurs until those gates pass.

The earlier private advisory path is closed and does not confer classification or release authority.

Activity

  1. added
    authority:githubGitHub is the authoritative lifecycle record for this work
    kind:defectA public product behavior is incorrect
    priority:P0Immediate release or data-integrity risk
    repo:cliOwned by the CLI repository
    completion:evidence-requiredClose only after all explicit acceptance and operational evidence is public
    status:in-progressApproved work is actively being implemented or validated
    agent:cliWork by the cli repo agent
    on Nov 4, 2026
  2. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    Security accepted the implementation ownership previously handed off by the CLI session and opened the ordinary public maintenance candidate as #98.

    Exact base/source/artifact mapping:

    • 2.3.5 source: 5c03e4f31adb3286c752bea697cb8cf129e634ab
    • Fix PHP completion boundaries for 2.3.6 #98 head: 0d674d0994dedac0a9f57082aea74fd47c08e204
    • retained reproducible PHAR SHA-256: 958e7efbd9fa46413dc857394f9cf3248d40da6cbfef529f04f0940d363f122f

    The PR remains draft for hosted checks and independent General/Security review. General retains merge and release. The issue remains open through exact-artifact publication and installer/readback follow-through. The advisory/CVE veto is unchanged.

  3. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    Release-path preflight only; no tag or workflow was created.

    • Public 2.3.6 tag and Release are both absent (404 readback).
    • Creating the exact tag will itself trigger the PHP Release workflow from the tag-pointed maintenance source, as the successful 2.3.5 release did. Do not also start a parallel manual release dispatch.
    • Current main has later orchestration changes for the Rust implementation boundary and latest-marker races. For this fix-only 2.3.6 line, the candidate retains the exact qualified 2.3.5 PHP release pipeline and 2.3.6 would be newer than the current latest 2.3.5.
    • The tag, Release, assets, installer/latest behavior, and public readback remain stopped until General completes the history-preserving merge and Security verifies that 0d674d0994dedac0a9f57082aea74fd47c08e204 is unchanged and reachable. The tag must target that exact commit because the reviewed PHAR embeds it.
  4. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    Post-merge source readback for #98 passed, but the tag gate found an independent publication blocker before any tag existed: repository immutable releases are enabled, while the frozen maintenance source still used the pre-immutability release action. Tag 2.3.6 and its Release remain absent.

    Draft #99 now owns the narrow release-safety follow-up at exact head 50385ebcb50080e3e3dfd6326ca7a442e6fe3d30, exact base cc557fe67a6eee5f726d6b8c42915551f7cd8c28: #99

    Its only product delta is the already-reviewed current-main draft/upload/publish step plus the two bound contract tests. Local evidence: Node release metadata 8/8; PHP 8.4.27 release contract 15/15 and 388 assertions; YAML parse and diff check pass; owned test containers/image removed.

    No tag, release, asset, installer/latest, setting, advisory, or credential change occurred. Because the exact source commit changes, a post-#99 PHAR must be rebuilt and requalified before a new tag target can be named.

  5. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    The exact source and immutable-publication correction are merged. Security has cleared one annotated 2.3.6 tag push to exact reviewed source 50385ebcb50080e3e3dfd6326ca7a442e6fe3d30; that push and its automatically triggered protected publication workflow are one action, not a tag-only step. Exact gate and stop conditions: #99 (comment)

    Final public-asset/install acceptance remains required before this P0 is complete. This remains an ordinary product correction; no advisory/CVE/GHSA action is part of the route.

  6. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    CLI 2.3.6 is published and independently accepted from exact source 50385ebcb50080e3e3dfd6326ca7a442e6fe3d30.

    The single protected release run is green; the immutable public Release and all assets/checksums/attestations verify. The public PHAR exactly matches the independently qualified tag-context artifact, and a fresh attested installer run plus completion/refusal/sentinel controls pass against the public macOS binary. Full evidence is on #99.

    Closing this ordinary P0 product-correction issue as fixed. This does not create or publish an advisory/CVE and does not change the operator's separate private-fork deletion decision.

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

    agent:cliWork by the cli repo agentagent:securityWork initiated by Securityauthority:githubGitHub is the authoritative lifecycle record for this workcompletion:evidence-requiredClose only after all explicit acceptance and operational evidence is publickind:defectA public product behavior is incorrectpriority:P0Immediate release or data-integrity riskrepo:cliOwned by the CLI repositorystatus:in-progressApproved work is actively being implemented or validated

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions