Security Policy

August 16, 2026 · View on GitHub

Reporting a vulnerability

Please do not open a public issue for security problems. Report them privately to the maintainer at github.com/tmpdot/dsh-checkpoint-diff/security/advisories (GitHub private vulnerability reporting) or by opening a private advisory through the repository's Security tab.

You can expect an acknowledgement within 5 business days and a coordinated fix/disclosure plan after triage.

Scope

This plugin is read-only by design, with one explicit exception — rollback:

  • it never writes to snapshot storage, git, or sessions, and never forks sessions;
  • its HTTP surface is a set of read-only GET endpoints plus two write endpoints — POST /checkpoint-diff/api/rollback and POST /checkpoint-diff/api/rollback-undo — both served by the harness webServer on the loopback interface;
  • the rollback endpoint is the only write path that changes workspace contents: it restores file contents from a checkpoint time node into the session workspace only. It never deletes files, never writes outside the workspace root, never follows symbolic links, and never touches .git/.dsh paths. Request bodies are capped (64 KiB) and JSON-validated; dryRun: true plans without writing.
  • rollback's single-shot undo (POST /api/rollback-undo, /rollback --undo) reverts the most recent restore in-process: it rewrites the pre-restore contents and may delete a file only when that restore itself created it (the pre-restore content was absent) — the one exception to "never deletes", exercised through the same path validations (normalized path inside the workspace root, real-file assertion, .git/.dsh refused). Undo entries live in process memory only (lost on restart), a file that changed since the restore is skipped (all skipped → 409), and there is no redo. The undo endpoint body is capped (64 KiB) and JSON-validated.

The attack surface that matters is stored-data integrity: checkpoint records live in the checkpoints storage domain, which is a human-readable medium (SQLite rows or JSON files) that a local actor could tamper with. The following defenses are load-bearing and must never be relaxed:

  • git refs are validated as ^[0-9a-f]{40,64}$ before being passed to any git command (no option injection through tampered records);
  • copy refs are validated as UUIDs and relative paths must not be absolute or contain .. (no path traversal out of the snapshot directory);
  • snapshot manifests are validated before use;
  • rollback restore paths are normalized and must not be absolute or contain ..; target writes resolve inside the workspace root and refuse symbolic links anywhere along the path; .git/.dsh segments are refused at any depth; the git provider refuses to roll back when the session cwd is not the repository root (snapshot tree paths are root-relative);
  • the preview-diff endpoint (GET /api/preview-diff) reads the workspace file only after the same normalized-path + protected-path checks and never follows symbolic links (lstat gate), so it cannot leak files outside the workspace or from .git/.dsh;
  • rollback-undo applies the same checks before every write or delete it performs.

Supported versions

VersionSupported
0.4.x:white_check_mark:
0.3.x:white_check_mark:

Older versions are unsupported; please upgrade.