Skip to content

Recursive remote cleanup can escape the intended directory through nested PowerShell/cmd quoting without a root-path safety stop #34512

Open

Description

@Sxl7939-dot

Summary

Codex intended to remove one temporary smoke-test directory in my own Parallels Windows 11 build VM. After PowerShell Remove-Item failed because a DLL was still locked, Codex automatically escalated to a stronger recursive deletion through a nested macOS shell → SSH → PowerShell -EncodedCommand → cmd.exe chain.

An incorrect PowerShell/cmd quoting pattern caused the operation to traverse the current Windows drive root instead of the intended temporary directory. The operation ran for approximately 59 seconds before a later tool input sent Ctrl-C.

This issue intentionally omits the complete executable deletion command. The original session is available privately through Codex feedback: 019f82c8-4c41-7f91-ab74-30b3d34c98dc.

OpenAI Support confirmed on 2026-07-21 that the conversation was escalated to a support specialist. Support case 11849398 has been issued.

Environment

  • Codex task ID: 019f82c8-4c41-7f91-ab74-30b3d34c98dc
  • Codex Desktop / recorded version: 0.145.0-alpha.18
  • Recorded model setting: gpt-5.6-sol, effort max
  • Host: macOS 27.0 (26A5378n)
  • Guest: Windows 11 under Parallels Desktop 26.3.3
  • Remote execution: SSH → PowerShell -EncodedCommand → cmd.exe
  • sandbox_policy.type: danger-full-access
  • approval_policy: never
  • permission_profile: disabled
  • Support case: 11849398

Expected behavior

  • A locked temporary directory should be left in place and reported as a non-blocking cleanup failure.
  • A recursive delete must remain inside the unique approved run directory.
  • The target OS should normalize and attest the final absolute path before deletion.
  • Drive roots, user profiles, Desktop, empty paths, unresolved variables, and run roots should be unconditionally rejected.
  • A stronger delete method should not be selected automatically after a safer cleanup method fails.

Actual behavior

  1. The final package self-check succeeded.
  2. PowerShell cleanup failed on a locked Pillow _imaging DLL.
  3. Codex described the lock as temporary and retried with a stronger recursive cmd.exe deletion.
  4. A backslash-based quote escape was used even though PowerShell does not use backslash to escape double quotes.
  5. No final normalized path, final argv, file count, size estimate, allow-root assertion, or root-deny check was shown before execution.
  6. Preserved output contained root-level paths including \pagefile.sys, \PROGRA~1\..., and \Users\....
  7. The output was recorded as 1,341 lines but truncated.
  8. There was no visible automatic output-anomaly stop. Ctrl-C was sent manually about 59.383 seconds after launch.

Context compaction facts

The rollout contains three compaction events in total:

  • 12:45:42.425 UTC+8
  • 14:11:50.009 UTC+8
  • 15:11:12.425 UTC+8, after the incident

Two compactions therefore occurred before the dangerous command. The latest was 42 minutes 08.604 seconds earlier.

I am not claiming compaction directly caused the incident. The exact smoke-test path was created after the second compaction, and the visible replacement history still contains a higher-level “do not clean or roll back user files” constraint. The compaction-summary bodies are encrypted in the local rollout, so only OpenAI can inspect the complete model-visible pre/post-compaction history.

Approval and remote-boundary concern

The user approved the RC6 build generally. There was no separate confirmation for this recursive deletion command. With approval_policy=never, the SSH tool call executed without an approval prompt.

The local sandbox did not directly delete the guest filesystem; the effect occurred through configured SSH credentials. This means local command safety needs to understand destructive payloads nested inside remote and encoded commands, or the remote worker must enforce its own immutable deletion boundary.

Impact and evidence

  • Visible Windows desktop state changed substantially.
  • Many system files returned access-denied/in-use errors.
  • Exact successful deletion list and recovery rate remain unknown.
  • I am not claiming that the entire VM was deleted.
  • The original rollout, Parallels logs, screenshots, and metadata were preserved.
  • After shutdown, a PVM file-level evidence copy was created and all 20 source-manifest files verified by SHA-256.
  • The VM had already restarted once before preservation, which is an explicit limitation.

Requested engineering changes

  1. Decode and inspect destructive payloads nested in SSH, PowerShell EncodedCommand, and cmd.exe before execution.
  2. Canonicalize the target path on the target OS and bind deletion to an approved directory handle or unique run identity.
  3. Hard-block drive roots, UNC roots, user-profile roots, Desktop, workspace roots, run roots, empty strings, and unresolved variables.
  4. Do not automatically escalate cleanup methods after a lock or access failure.
  5. Require a two-phase dry-run summary with normalized path, count, size, and boundary assertions.
  6. Require a fresh, non-bypassable confirmation for large recursive deletion even in full-access/no-approval modes.
  7. Add an execution-supervisor kill switch when streamed output suddenly shows system-root or out-of-scope paths.
  8. Add negative tests for Bash → SSH → PowerShell → cmd quoting, spaces, trailing slashes, empty variables, current-drive roots, UNC paths, and encoded commands.
  9. Preserve final argv, normalized target, approval decision, and timestamped output for incident review.
  10. After repeated compaction, rehydrate and display the original destructive-operation boundaries before proceeding.

Private evidence references

  • Codex feedback session: 019f82c8-4c41-7f91-ab74-30b3d34c98dc
  • OpenAI Support case: 11849398
  • Security report, if applicable: N/A — no separate security report filed at time of issue creation

Please let me know the safest private channel for the raw JSONL and logs. They contain local paths and will not be attached publicly without further redaction.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    windows-osIssues related to Codex on Windows systems
    safety-checkIssues related to safety and abuse checks
    tool-callsIssues related to tool calling
    sandboxIssues related to permissions or sandboxing
    on Jul 21, 2026
  2. github-actions commented on Jul 21, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. Sxl7939-dot commented on Jul 21, 2026

    @Sxl7939-dot
    Author

    Thanks for flagging #33624. I reviewed it. The issues overlap at the defense-in-depth level, but this report is not a duplicate of that incident:

    OpenAI Support case: 11849398.

    I am keeping this issue open so maintainers can investigate the specific nested-shell quoting failure, remote-boundary enforcement, final-path/argv validation, and missing output-based automatic stop. I am happy to cross-reference or consolidate if a maintainer requests it.

  4. Sxl7939-dot commented on Jul 22, 2026

    @Sxl7939-dot
    Author

    Quantitative forensic update — 2026-07-22

    Offline analysis of a derived, read-only working copy of the preserved Windows NTFS virtual disk has now established a confirmed lower bound for the impact described in this issue.

    Retained USN evidence

    • The first continuous retained FILE_DELETE burst contains 350,976 unique deletion records:
      • 322,445 file entries
      • 28,531 directory entries
    • All 350,976 paths were reconstructed; 350,971 are under C:\Users\codex.
    • Retained burst: 2026-07-21 14:54:35.891981–14:55:11.251881 (UTC+8).
    • The retained USN journal begins 37.278981 seconds after the dangerous call started. Therefore, 350,976 is a confirmed minimum, not a total-loss estimate; records from the missing initial interval may no longer be available.
    • FILE_DELETE|CLOSE records continued for 13.255881 seconds after the recorded Ctrl-C. This proves continued filesystem activity after Ctrl-C, but USN alone does not identify the responsible process for every record or prove that one process remained actively responsible throughout that interval.

    Scope and recovery-candidate metadata

    The raw count includes many generated or replaceable artifacts: 332,613 records are under codex-win\runs. Confirmed affected scope also includes:

    • codex-win\work: 6,152 records across named project, review, code-protection validation, and rework workspaces;
    • Desktop: 82 records;
    • Documents: 4 records;
    • Downloads: 2 records.

    A focused MFT metadata check covered these 6,240 key-path records:

    • 6,010 currently unallocated MFT records still retain the original deleted name;
    • 230 record slots were reused or no longer retain the original name;
    • 5,425 file records retain logical-size metadata totaling 3,897,486,794 bytes (~3.90 GB).

    These are metadata-level recovery candidates only. They do not prove that content clusters are intact, recoverable, or already recovered. I am still not claiming that the entire VM was deleted.

    Ten bounded analysis outputs (TSV, JSON, and a forensic conclusion) verified 10/10 OK against their SHA-256 manifest. Detailed path lists and raw evidence remain private pending a secure transfer channel.

    OpenAI Support case: 11849398. I have sent the same quantitative update to Support and requested confirmation of server-side record preservation and transfer to Codex engineering/product safety.

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

    appIssues related to the Codex desktop appbugSomething isn't workingremotesafety-checkIssues related to safety and abuse checkssandboxIssues related to permissions or sandboxingtool-callsIssues related to tool callingwindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions